%    \iffalse meta-comment
%    \begin{macrocode}
%<*answers>
\def\fileversion{2.10}
\def\filedate{16 Dec 1997 17:05:29 BST}
\def\filename{answers.dtx}
\def\Copyright{Copyright (C) 1990,1994 Mike Piff,
   University of Sheffield, England}
%</answers>
%    \end{macrocode}
%
%You are not allowed to change this file.
%
%You are NOT ALLOWED to distribute this file alone.  You are NOT
%ALLOWED to take money for the distribution or use of this
%file except for a nominal charge for copying etc.
%
%Please address any problems to:
%
%M.Piff@shef.ac.uk
%
%For updates, contact your nearest CTAN site.
%
%    \fi
%
%    \CheckSum{248}
%
% \changes{2.0}{1994/03/25}{First version for LaTeX2e}
% \changes{2.01}{1994/03/30}{Whoops! |ProvidesPackage{answers}|,
%           not |ProvidesClass{Answers}|!!}
% \changes{2.02}{1995/08/31}{Removed .drv file from installation}
% \changes{2.03}{1995/08/31}{Allowed a file handle to open
%           many files successively, using an optional parameter.}
% \changes{2.04}{1995/09/08}{Option nosolutionfiles added to allow
%           solutions to optionally follow problems for tutor's use.
%           Several minor changes to aid flexibility}
% \changes{2.05}{1995/09/11}{Better documentation of features added}
% \changes{2.06}{1996/01/05}{More documentation of features added,
%           as suggested by David Epstein.}
% \changes{2.07}{1996/01/08}{Conditionals to check if files were open
%           were not changed globally. (Spotted by David Epstein.)}
% \changes{2.08}{1996/01/11}{More examples added.}
% \changes{2.09}{1996/07/10}{Bug spotted by David Epstein;
%           I had missed out the definition of the boolean that
%           checks if a file is open!  Ah well!}
%
%
%
%    \title{Production of solution sheets in \LaTeXe}
%    \author{Copyright (C) 1994,1995 by Mike Piff}
%
%    \maketitle
%    \tableofcontents
%
%    \section{Introduction}
%
%    This package is a modification of the author's previous style option
%    |answers|, which has been in use for a few years,
%    and was based upon the
%    \TeX book idea of binding solutions to exercises. I have taken the
%    opportunity with this revision to alter the format of the solutions,
%    so that they are now presented as \LaTeX\ environments rather than
%    being started with a command and ended with the end of the surrounding
%    environment, a wholly un-\LaTeX y way of doing things!
%
%    The other main change is that several file
%    handles are allowed to be active
%    at once. This allows some solutions in a book (for instance) to go
%    to the appendices, and some to go to a separate file, to be printed and
%    handed to the students as the course progresses.
%    Moreover, the actual physical files opened with each file handle
%    can now be varied in the same job, allowing many different files
%    to be created according to the same format.  Thus, for instance,
%    each chapter of a book could create its own solution file, allowing
%    the user to use |\include| on both chapters and solutions.
%
%    Finally, any number of solution-types may now be bound to any file, not
%    just the two old ones, solution and hint.   The format of each solution
%    type is under the complete control of the user.
%
%    \section{The documentation driver file}
%
%    This is the driver file that produces this documentation.
%    We use the document class provided by the \LaTeXe\ distribution
%    for producing the documentation.
%    \begin{macrocode}
%<*driver>
\documentclass{ltxdoc}
\RecordChanges
\begin{document}
  \DocInput{answers.dtx}
  \PrintIndex
  \PrintChanges
\end{document}
%</driver>
%    \end{macrocode}
%    
%    \section{User interface}
%
%    The package needs to be included with the command
%    \begin{verbatim}
%             \usepackage[nosolutionfiles]{answers}
%    \end{verbatim}
%    If the optional argument is given, solutions appear at that point
%    in the text, rather than being written to external files.
%    This allows a demonstrator's version to be produced.
%
%    \DescribeMacro{\Newassociation}
%    After that, there should be several declarations of the form
%    \begin{verbatim}
%        \Newassociation{xxx}{yyy}{zzz}
%    \end{verbatim}
%    where |xxx| is an environment in the document, and |yyy| is an
%    environment which will surround the contents of |xxx| when it is
%    written to symbolic file handle |zzz|.
%    The names |xxx|, |yyy| and |zzz| should consist of letters
%    only, not numbers, punctuation or spaces.
%
%    \DescribeMacro{\solutionextension}
%    By default, output will go to |zzz.tex| if |zzz| is open.
%    The command |\solutionextension| can be redefined to change |tex| to
%    some other extension.  Alternatively, the output filename can be
%    changed as an optional parameter to |\Opensolutionfile|, and each
%    |\Opensolutionfile| on the same handle can use a different physical
%    file.  By default, |\solutionpoint| is added before |\solutionextension|.
%	  Redefine it to remove it. (It has the obvious default value of a
%    period.
%
%    \DescribeMacro{\Opensolutionfile}
%    \DescribeMacro{\Closesolutionfile}
%    At some point the user types
%    \begin{verbatim}
%        \Opensolutionfile{zzz}
%        ...
%        \Closesolutionfile{zzz}
%    \end{verbatim}
%    to create a file of solutions written by environments |xxx| to
%    environments |yyy|.
%    If this construction is used several times, then several files
%    of solutions will be created.
%    The user may wish these files to have different names.
%    If the form |\Opensolutionfile{zzz}[www]|, then |www.tex| is used as
%    actual file output name rather than |zzz.tex|.   This allows file
%    handle |zzz| to create many files |www.tex|, say one for each
%    chapter of a book, or one for each problem sheet.  These could then
%    be processed using |\include| commands.  The same value of
%    |\solutionextension| is used for the optional argument as for the
%    main argument.
%    The name |www| should follow the usual file naming conventions.
%
%    \DescribeMacro{\Writetofile}
%    In addition, material can be written directly to a file by means of
%    |\Writetofile|.
%    Its first argument is the file handle |zzz| and its second is
%    the line of text to be written.
%    It is  most important to remember that any control words
%    in the line to be written should be preceded by |\protect|,
%    otherwise the primitive \TeX\ |\write| command will expand them.
%    Also, as the argument is read in \TeX' usual way before being
%    written, any trailing spaces after a control word will disappear
%    unless precautions are taken.  Thus, to write |\xx yyy| to the file,
%    the user can type |\protect\xx\space yyy|.
%
%    \DescribeEnv{Filesave}
%    Alternatively, a block of text can be saved to file handle
%    |zzz| by means of
%    \begin{verbatim}
%        \begin{Filesave}{zzz}
%           ....
%        \end{Filesave}
%    \end{verbatim}
%    around it once, |zzz| has been opened.
%    The restrictions that apply to |\Writetofile| above do not apply
%    to this environment.
%
%    \DescribeMacro{\Readsolutionfile}
%    One of the generated files can be read using
%    \begin{verbatim}
%        \Readsolutionfile{zzz}
%    \end{verbatim}
%    provided the file has not been closed and re-opened.
%    Alternatively, simply |\input| or |\include| it if preferred.
%
%     None of the file operations should have any effect if the file
%     handle |zzz| has not been opened, or if |nosolutionfiles| is specified.
%
%    \section{A simple example}
%
%    Here is a straightforward example to illustrate how these macros
%    are used.
%    \begin{macrocode}
%<*ex1>
\documentclass[12pt,a4paper]{article}
\usepackage{answers}
\Newassociation{sol}{Solution}{ans}
\newtheorem{ex}{Exercise}
\begin{document}
\Opensolutionfile{ans}[ans1]
\section{Problems}
\begin{ex}
   First exercise
   \begin{sol}
      First solution.
   \end{sol}
\end{ex}
\begin{ex}
   Second exercise
   \begin{sol}
      Second solution.
   \end{sol}
\end{ex}
\Closesolutionfile{ans}
\section{Solutions}
\input{ans1}
\end{document}
%</ex1>
%    \end{macrocode}
%
%    \section{A complicated example}
%
%    The following is an (over-complicated) example of the use
%    of package |answers|.
%    It uses some of the refinements described later.
%    \begin{macrocode}
%<*ex2>
\documentclass[12pt,a4paper]{article}
\usepackage{answers}%\usepackage[nosolutionfiles]{answers}
%    \end{macrocode}
%    First an environment which contains problems and numbers them.
%    This is based on a \LaTeX\ theorem, but with a roman body
%    rather than italic.
%    \begin{macrocode}
\newtheorem{Exc}{Exercise}
\newenvironment{Ex}{\begin{Exc}\normalfont}{\end{Exc}}
%    \end{macrocode}
%    Three sorts of solution are written to two different files.
%    File handle |test| will contain the solutions and hints that the
%    students will see; |testtwo| contains the solutions to the
%    problems which they will probably hand in, and so these must be
%    formatted separately.
%    \begin{macrocode}
\Newassociation{solution}{Soln}{test}
\Newassociation{hint}{Hint}{test}
\Newassociation{Solution}{sSol}{testtwo}
%    \end{macrocode}
%    Because we want to mark different types of problem in the master file of
%    problems, we define the following.
%    \begin{macrocode}
\newcommand{\prehint}{~[Hint]}
\newcommand{\presolution}{~[Solution]}
\newcommand{\preSolution}{~[Homework]}
%    \end{macrocode}
%    We provide an extra parameter when we open file handle |test|;
%    this is because we want to write a |\section| command to the
%    solution file.  This is merely an illustration here, but would be
%    more relevant if the solution file were |\include|d.
%    \begin{macrocode}
\newcommand{\Opentesthook}[2]%
   {\Writetofile{#1}{\protect\section{#1: #2}}}
%    \end{macrocode}
%    The default text produced when \LaTeX meets the solution
%    environments is here modified.
%    \begin{macrocode}
\renewcommand{\Solnlabel}[1]{\emph{Solution #1}}
\renewcommand{\Hintlabel}[1]{\emph{Hint #1}}
\renewcommand{\sSollabel}[1]{\emph{Solution to #1}}

\begin{document}
%    \end{macrocode}
%    We open handle |test| as actual file |test1.tex|,
%    \begin{macrocode}
   \Opensolutionfile{test}[ans2]{Solutions}
%    \end{macrocode}
%    and write some text on it.
%    \begin{macrocode}
   \Writetofile{test}{\protect\subsection{Some Solutions}}
%    \end{macrocode}
%    Handle |testtwo| is opened as |testtwo.tex|.
%    \begin{macrocode}
   \Opensolutionfile{testtwo}[ans2x]
   \Writetofile{testtwo}{%
      \protect\subsection{Extra Solutions}}
%    \end{macrocode}
%    Now the problems.
%    \begin{macrocode}
   \section{Exercises}
   \begin{Ex}
      An exercise with a solution.
      \begin{solution}
         This is a solution.
         \relax{}
      \end{solution}
   \end{Ex}
   \begin{Ex}
      An exercise with a hint and a secret solution.
      \begin{hint}
         This is a hint.
      \end{hint}
      \begin{Solution}
         This is a secret solution.
      \end{Solution}
   \end{Ex}
   \begin{Ex}
      An exercise with a hint.
      \begin{hint}
         This is a hint.
      \end{hint}
   \end{Ex}
%    \end{macrocode}
%    We close the two solution files and immediately input their
%    contents.  We could have used |\include| here.
%    \begin{macrocode}
   \Closesolutionfile{test}
   \Readsolutionfile{test}
   \clearpage
   \Closesolutionfile{testtwo}
   \Readsolutionfile{testtwo}
\end{document}
%</ex2>
%    \end{macrocode}
%
%    \section{A further example}
%
%    Here is an application to a situation not originally envisaged,
%    suggested to the author by Martin Osborne.  Here, the exercises and
%    solutions are not numbered; they are \emph{described}.
%    \begin{macrocode}
%<*ex3>
\documentclass[12pt,a4paper]{article}
\usepackage{answers}
\newenvironment{Ex}[1]{\begin{trivlist}\item \emph{#1} %
   \renewcommand{\Currentlabel}{#1}}{\end{trivlist}}
\Newassociation{solution}{Soln}{solutions}

\renewenvironment{Soln}[1]{\begin{trivlist}\item
   Solution to \emph{#1} }{\end{trivlist}}

\begin{document}
\section*{Problems}
   \Opensolutionfile{solutions}[ans3]
   \begin{Ex}{First exercise}
      An exercise with a solution.
      \begin{solution}
         This is a solution.
         \relax{}
      \end{solution}
   \end{Ex}
   \begin{Ex}{Second exercise}
      A second exercise with a solution.
      \begin{solution}
         This is another solution.
      \end{solution}
   \end{Ex}
   \Closesolutionfile{solutions}
\section*{Solutions}
   \Readsolutionfile{solutions}
\end{document}
%</ex3>
%    \end{macrocode}
%
%    \StopEventually{}
%
%
%    \section{Identification}
%
%    This package can only be used with \LaTeXe, so
%    an appropriate message is displayed when another
%    format is used.
%    \begin{macrocode}
%<*answers>
\NeedsTeXFormat{LaTeX2e}[1996/06/01]
%    \end{macrocode}
%
%
%    Announce the package name and its version:
%    \begin{macrocode}
\ProvidesPackage{answers}[1996/07/10]
%    \end{macrocode}
%
%     And display it on the terminal (and the log file):
%    \begin{macrocode}
\typeout{Package `answers' <\filedate>.}
\typeout{\Copyright}
%    \end{macrocode}
%
%  \section{Options}
%
%  There is a single option |nosolutionfiles| that
%  switches output off to files
%  and produces the solutions here-and-now.
%
%    \begin{macrocode}
\newif\ifanswerfiles \answerfilestrue
\DeclareOption{nosolutionfiles}{\answerfilesfalse
   \typeout{No answer files being produced}}%
\ProcessOptions

%    \end{macrocode}
%
%
%    As this package now relies heavily on the |verbatim| package, we
%    ensure that that is loaded.
%    \begin{macrocode}
\RequirePackage{verbatim}
%    \end{macrocode}
%
%
%    \section{File handling}
%
%    \begin{macro}{\solutionextension}
%    The default extension for solution files is defined here.
%    \begin{macrocode}
\newcommand{\solutionpoint}{.}
\newcommand{\solutionextension}{tex}
%    \end{macrocode}
%    It may be changed with |\renewcommand|.
%    \end{macro}
%
%    \begin{environment}{Filesave}
%    We define an environment |Filesave| with one parameter, the file handle.
%    It is similar to the example of Sch\"opf in the
%    description of |verbatim|.
%    \begin{macrocode}
\newenvironment{Filesave}[1]{%
   \@bsphack
   \def\verbatim@processline{}%
   \Iffileundefined{#1}{}{%
      \Ifopen{#1}{%
         \def\verbatim@processline{%
            \Ifanswerfiles{%
               \immediate\write\@nameuse{#1@file}%
                  {\the\verbatim@line}%
            }{}%
         }%
      }{}%
   }%
   \let\do\@makeother\dospecials
   \catcode`\^^M\active \catcode`\^^I=12\relax
   \verbatim@start
}{\@esphack}
%    \end{macrocode}
%    \end{environment}
%
%    \begin{macro}{\Writetofile}
%    It is also useful to have a command to write material to the file.
%    In this, you need to put |\protect| before any control words in the
%    argument that might expand prematurely and create havoc.
%    \begin{macrocode}
\newcommand{\Writetofile}[2]{%
   \@bsphack
   \Iffileundefined{#1}{}{%
      \Ifopen{#1}{%
         {%
            \let\protect\string
            \Ifanswerfiles{%
               \immediate\write\@nameuse{#1@file}{#2}%
            }{}%
         }%
      }{}%
   }%
   \@esphack
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\Ifopen}
%    We need to check whether or not a file is already open.
%    \begin{macrocode}
\newcommand{\Ifopen}[3]{%
   \csname if#1open\endcsname#2\else#3\fi}%
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\Iffileundefined}
%    We also need to check whether a file variable has already been defined
%    for a given file handle.
%    \begin{macrocode}
\newcommand{\Iffileundefined}[3]{%
   \csname ifx\expandafter\endcsname
      \csname #1@file\endcsname\relax
      #2\else#3\fi}
%    \end{macrocode}
%    \end{macro}
%    Finally, we need a check as to whether we are outputting answers to a
%    file or not
%    \begin{macrocode}
\newcommand{\Ifanswerfiles}[2]{%
   \ifanswerfiles #1\else #2\fi}
%    \end{macrocode}
%
%
%
%    \section{The file interface}
%
%    \begin{macro}{\Opensolutionfile}
%    Before we can write solutions, we must open the solution file(s).
%    The command to do this takes a single parameter, which should usually be
%    a file name without extension. Thus it should probably be
%    restricted to a string of at most 8 letters for portability.
%    This operation will not truncate any existing open file.
%    However, if the second optional parameter is specified, this
%    determines the actual filename, and the first parameter is then
%    an arbitrary symbolic file handle name.
%    \begin{macrocode}
\def\Opensolutionfile#1{%
   \@ifnextchar[{\define@filename{#1}}%
      {\define@filename{#1}[#1]}}%
\def\define@filename#1[#2]{%
   \global\@namedef{#1@filename}{#2\solutionpoint\solutionextension}%
   \Ifanswerfiles{%
      \typeout{Output from handle #1 going
         to #2.\solutionextension}%
   }{}%
   \Iffileundefined{#1}{%
      \expandafter\newwrite\csname #1@file\endcsname
      \csname newif\expandafter\endcsname
         \csname if#1open\endcsname
      \global\csname #1openfalse\endcsname
      \expandafter\ifx\csname Open#1hook\endcsname\relax
         \global\@namedef{Open#1hook}##1{}%
      \fi
      \expandafter\ifx\csname Close#1hook\endcsname\relax
         \global\@namedef{Close#1hook}##1{}%
      \fi
   }{}%
   \let\Tmp\relax
   \Ifopen{#1}{\typeout{File #1 already open}}{%
      \Ifanswerfiles{%
         \immediate\openout\@nameuse{#1@file}=%
         \@nameuse{#1@filename}%
      }{}%
      \global\csname#1opentrue\endcsname
      \def\Tmp{\@nameuse{Open#1hook}{#1}}%
   }%
   \Tmp
}
%    \end{macrocode}
%    \begin{macro}{\Closesolutionfile}
%    We also have a command to close an already open file.
%    \begin{macrocode}
\def\Closesolutionfile#1{%
   \let\Tmp\relax
   \Iffileundefined{#1}{}{%
      \Ifopen{#1}{%
         \Ifanswerfiles{%
            \immediate\closeout\@nameuse{#1@file}%
         }{}%
         \global\csname #1openfalse\endcsname
         \def\Tmp{\@nameuse{Close#1hook}{#1}}%
      }{}%
   }%
   \Tmp
}
%    \end{macrocode}
%
%    Note that the two file commands each provide a hook which allows them to
%    perform extra tasks.
%    For instance, the opening operation could be made to
%    write extra information to the file by redefining the appropriate hook.
%    The closing operation could if required do an immediate |\input| of the
%    solution file contents. For example,
%    \begin{verbatim}
%        \newcommand{\Openxxxhook}[2]{%
%           \Writetofile{#1}{\protect\section{#2}}%
%        }%
%        \newcommand{\Closexxxhook}[1]{%
%           \Readsolutionfile{#1}%
%        }
%    \end{verbatim}
%    and then
%    \begin{verbatim}
%        \Opensolutionfile{xxx}{Answers to selected problems}
%        ...
%        \Closesolutionfile{xxx}
%    \end{verbatim}
%    The default behaviour is to ignore the one parameter. Note that if you
%    redefine their behaviour, you must remember that the first parameter is
%    always the file handle.
%    \end{macro}
%    \end{macro}
%
%    \begin{macro}{\Readsolutionfile}
%    The operation of reading the file of solutions can be done with the
%    following command.
%    \begin{macrocode}
\def\Readsolutionfile#1{%
   \Ifanswerfiles{%
      \Iffileundefined{#1}{}{%
         \Ifopen{#1}{%
            \typeout{WARNING: attempt to read open file #1}%
         }{%
            \edef\Tmp{%
               \noexpand\InputIfFileExists
                  {\@nameuse{#1@filename}}{}%
               {\noexpand\message{File
                  \@nameuse{#1@filename}%
                     \space not found}}%
            }%
            \Tmp
         }%
      }%
   }{}%
}

%    \end{macrocode}
%    \end{macro}
%
%
%    \section{The solution interface}
%
%    \begin{macro}{\Newassociation}
%    Several solution file handles may have been defined.
%    You are limited only by the
%    number that \TeX\ will make available to you. Each solution environment
%    that is to write to one of these handles
%    must know which handle to write to,
%    and also what extra information to write there, apart from its contents.
%    This is done by setting up an association
%    between the source environment,
%    the destination environment and the file handle.
%    \begin{macrocode}
\newcommand{\Newassociation}[3]{%
   \newsolution{#2}%
   \expandafter\ifx\csname #3opentrue\endcsname\relax
      \expandafter\newif\csname if#3open\endcsname
   \fi
   \newenvironment{#1}{%
      \Ifanswerfiles{%
         \let\Tmp\relax
         \Iffileundefined{#3}{}{%
            \Ifopen{#3}{%
               \immediate\write\@nameuse{#3@file}%
                  {\string\begin{#2}\@nameuse{#2params}}%
            \def\Tmp{\Filesave{#3}}%
            }{}%
         }%
      }{%
         \edef\Tmp{\noexpand\begin{#2}\@nameuse{#2params}}%
      }%
      \csname pre#1\endcsname
      \Tmp
   }%
   {%
      \Ifanswerfiles{%
         \Iffileundefined{#3}{}{%
            \Ifopen{#3}{%
               \endFilesave%
               \immediate\write\@nameuse{#3@file}%
                  {\string\end{#2}}%
               \csname post#1\endcsname
            }{}%
         }%
      }{%
         \end{#2}%
      }%
   }%
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\newsolution}
%    The default destination environment in the solution file is defined to
%    take a single parameter, a reference number inherited from the source
%    environment.  This is set with style |\solutionstyle|, which defaults
%    to |\textbf|.  In addition, solution type |yyy| can have markup added
%    before and after it by defining |\preyyy| and |\postyyy| suitably,
%    eg, a rule across the width of the page or a square.
%    If anything more sophisticated is intended, it is probably better to
%    |\renewenvironment{yyy}| to achieve it.
%    \begin{macro}{\Currentlabel}
%    \begin{macrocode}
\newcommand{\newsolution}[1]{%
   \@ifundefined{#1}{%
      \global\@namedef{#1params}{{\Currentlabel}}%
      \newenvironment{#1}[1]%
      {%
         \csname pre#1\endcsname
         \trivlist
         \item[\hskip\itemsep{\@nameuse{#1label}{##1}}]}%
      {\csname post#1\endcsname\endtrivlist}%
      \global\@namedef{#1label}##1{\solutionstyle{##1}}%
   }{\typeout{WARNING: environment #1 already in use}}%
}
\newcommand{\solutionstyle}[1]{\textbf{#1}}
\newcommand{\Currentlabel}{\@currentlabel}
%    \end{macrocode}
%    The format of the label for solution environment |xxx| is governed
%    by the command |\xxxlabel|, which takes one argument by default.
%    The argument is passed to it by the command |\xxxparams|,
%    which expands to |{\Currentlabel}|, a synonym for |{\@currentlabel}|,
%    and this argument is written automatically by the source environment.
%    The label appears in boldface by default.
%    We could easily change the behaviour of this environment by changing
%    these two commands. For example
%    \begin{verbatim}
%        \renewcommand{\xxxlabel}[1]{\emph{Solution to #1}}
%        \renewcommand{\xxxparams}{{\Currentlabel(p.\thepage)}}
%    \end{verbatim}
%    would provide a number and page reference in italic.
%
%    More complicated behaviour could be produced by redefining the |xxx|
%    environment itself to take a different number of parameters. Note
%    however that |\xxxparams| must be redefined to provide those parameters.
%    \end{macro}
%    \end{macro}
%
%    Which brings us to the end of the |answers| package.
%    \begin{macrocode}
%</answers>
%    \end{macrocode}
%
%
%
% \Finale
%
\endinput
%
