Non-typesetting of answers. Reading in answers from another document.
authormdw <mdw>
Fri, 5 Sep 2003 16:10:41 +0000 (16:10 +0000)
committermdw <mdw>
Fri, 5 Sep 2003 16:10:41 +0000 (16:10 +0000)
exercise.dtx

index 5b01925..3fbd1d3 100644 (file)
@@ -1,14 +1,17 @@
 % \begin{meta-comment}
 %
 % \begin{meta-comment}
 %
-% $Id: exercise.dtx,v 1.1 2002/02/03 20:49:03 mdw Exp $
+% $Id: exercise.dtx,v 1.2 2003/09/05 16:10:41 mdw Exp $
 %
 % Exercises
 %
 %
 % Exercises
 %
-% (c) 2001 Mark Wooding
+% (c) 2003 Mark Wooding
 %
 %----- Revision history -----------------------------------------------------
 %
 % $Log: exercise.dtx,v $
 %
 %----- Revision history -----------------------------------------------------
 %
 % $Log: exercise.dtx,v $
+% Revision 1.2  2003/09/05 16:10:41  mdw
+% Non-typesetting of answers.  Reading in answers from another document.
+%
 % Revision 1.1  2002/02/03 20:49:03  mdw
 % Checkin for new build system.
 %
 % Revision 1.1  2002/02/03 20:49:03  mdw
 % Checkin for new build system.
 %
@@ -18,7 +21,7 @@
 % \begin{meta-comment} <general public licence>
 %%
 %% exercise package -- useful macros for setting exercises with answers
 % \begin{meta-comment} <general public licence>
 %%
 %% exercise package -- useful macros for setting exercises with answers
-%% Copyright (c) 2001 Mark Wooding
+%% Copyright (c) 2003 Mark Wooding
 %%
 %% This program is free software; you can redistribute it and/or modify
 %% it under the terms of the GNU General Public License as published by
 %%
 %% This program is free software; you can redistribute it and/or modify
 %% it under the terms of the GNU General Public License as published by
 % \begin{meta-comment} <Package preambles>
 %<+package>\NeedsTeXFormat{LaTeX2e}
 %<+package>\ProvidesPackage{exercise}
 % \begin{meta-comment} <Package preambles>
 %<+package>\NeedsTeXFormat{LaTeX2e}
 %<+package>\ProvidesPackage{exercise}
-%<+package>                [2001/09/21 1.0 Exercies with answers]
+%<+package>                [2003/08/25 1.1 Exercies with answers]
 % \end{meta-comment}
 %
 % \end{meta-comment}
 %
-% \CheckSum{236}
+% \CheckSum{271}
 %% \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
 %% \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
@@ -65,6 +68,7 @@
 \input{mdwtools}
 \describespackage{exercise}
 \let\epsilon\varepsilon
 \input{mdwtools}
 \describespackage{exercise}
 \let\epsilon\varepsilon
+\errorcontextlines\maxdimen
 \mdwdoc
 %</driver>
 %
 \mdwdoc
 %</driver>
 %
 %\end{demo}
 % \end{figure}
 %
 %\end{demo}
 % \end{figure}
 %
+% \DescribeMacro\skipanswer
+% The |\skipanswer| command is similar, but just skips over the answer rather
+% than writing it to the output file.  It does nothing at all with counters
+% -- it's as if there was no answer given at all.
+%
+% It's OK to use commands like |\answer| and |\skipanswer| in your own
+% macros as long as they're the \emph{last} token.  You can therefore say
+% something like
+%\begin{verbatim}
+%\newcommand{\evenanswer}{%
+%  \ifthenelse%
+%    {\isodd{\value{exercise}}}%
+%    {\answer}%
+%    {\skipanswer}%
+%}
+%\end{verbatim}
+% to get just the answers to the odd-numbered problems.  (If you don't like
+% \package{ifthen} then you'll need to play with |\expandafter| for a bit.)
+%
 % \subsection{The answers file}
 %
 % \DescribeMacro\answrite
 % \subsection{The answers file}
 %
 % \DescribeMacro\answrite
 %\answers
 %\end{demo}
 %
 %\answers
 %\end{demo}
 %
+% The |\answers| command has an optional argument, which is the file to read
+% in.  This allows you to make `answer booklet' documents, by saying
+% something like
+%\begin{verbatim}
+%\answers[otherdoc]
+%\end{verbatim}
+% If you don't give a file extension, then |.ans| is appended automatically.
+%
 % \implementation
 % 
 %
 % \implementation
 % 
 %
 %
 % \subsection{Initialization}
 %
 %
 % \subsection{Initialization}
 %
-% The \textsf{within} option is handled by the \package{keyval} package.
+% The \textsf{within} option is handled by the \package{mdwkey} package.
 %
 %    \begin{macrocode}
 %
 %    \begin{macrocode}
-\RequirePackage{keyval}
+\RequirePackage{mdwkey}
 %    \end{macrocode}
 %
 % \begin{macro}{\ex@within}
 %    \end{macrocode}
 %
 % \begin{macro}{\ex@within}
 %
 %    \begin{macrocode}
 \let\ex@within\relax
 %
 %    \begin{macrocode}
 \let\ex@within\relax
-\define@key{ex}{within}{%
+\mkdef{exercise:opts}{within}{%
   \def\ex@within{%
     \@addtoreset{exercise}{#1}%
     \toks@\expandafter{\csname the#1\expandafter\endcsname%
   \def\ex@within{%
     \@addtoreset{exercise}{#1}%
     \toks@\expandafter{\csname the#1\expandafter\endcsname%
 %
 % \begin{macro}{\ex@opts}
 %
 %
 % \begin{macro}{\ex@opts}
 %
-% The |\ex@opts| macro just runs the \package{keyval} kit to parse an option
+% The |\ex@opts| macro just runs the \package{mdwkey} kit to parse an option
 % string.
 %
 %    \begin{macrocode}
 % string.
 %
 %    \begin{macrocode}
-\def\ex@opts{\setkeys{ex}}
+\def\ex@opts{\mkparse{exercise:opts}}
 %    \end{macrocode}
 % \end{macro}
 %
 %    \end{macrocode}
 % \end{macro}
 %
 %    \end{macrocode}
 % \end{macro}
 %
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\skipanswer}
+%
+% This is much simpler.
+%
+%    \begin{macrocode}
+\let\skipanswer\ignore
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\answers}
 %
 % The |\answers| macro closes the file, makes sure that future
 % \begin{macro}{\answers}
 %
 % The |\answers| macro closes the file, makes sure that future
 %
 %    \begin{macrocode}
 \def\answers{%
 %
 %    \begin{macrocode}
 \def\answers{%
+  \@ifnextchar[{\answers@i\input}{\answers@i\@input[\ex@ansfilename]}%
+}
+\def\answers@i#1[#2]{%
   \immediate\closeout\ex@ansfile%
   \global\let\answrite\exerr@toolate%
   \immediate\closeout\ex@ansfile%
   \global\let\answrite\exerr@toolate%
-  \input{\ex@ansfilename}%
+  \ex@withext{#1}{#2}{ans}%
+}
+\def\q@delim{\q@delim}
+\def\ex@withext#1#2#3{%
+  \edef\next@##1{\noexpand\ex@ext@i{##1}{#2}{#3}#2.\noexpand\q@delim}%
+  \next@{#1}%
+}
+\def\ex@ext@i#1#2#3#4.#5\q@delim{%
+  \ifx\q@delim#5\q@delim\def\next@{#1{#2.#3}}%
+  \else\def\next@{#1{#2}}\fi%
+  \next@%
 }
 %    \end{macrocode}
 % \end{macro}
 }
 %    \end{macrocode}
 % \end{macro}
 \def\exerr@parlist{%
   \PackageError{exercise}{You can't nest a `list' inside a `parlist'.}{%
     I've found a `list' or `trivlist' environment nested inside^^J%
 \def\exerr@parlist{%
   \PackageError{exercise}{You can't nest a `list' inside a `parlist'.}{%
     I've found a `list' or `trivlist' environment nested inside^^J%
-    a `parlist'.  This isn't allowed.%
+    a `parlist'.  This isn't allowed.  You're probably doomed now.%
   }%
 }
 %</package>
   }%
 }
 %</package>