Knuth’s approach is very plain-TeX oriented. Presumably what you really want to do is be able to have in your document, e.g.,
\begin{question}
What is 6 times 9?
\end{question}
\begin{answer}
42
\end{answer}
...
\chapter{Answers to questions}
\printanswers
And have all the contents of the answer environments only output with \printanswers.
I’ve done exactly this using the approach of saving the contents of the answer environment to a file (plus a bit of wrapper) to make it possible to produce the output with \printanswers. Here's the code that I used:
\RequirePackage{verbatim} % ❶
\newwrite\ans@out % ❷
\def\answer@chapstart{\immediate\openout\ans@out=\jobname.ans} % ❸
\def\answer{%
\@bsphack % ❹
\let\do\@makeother\dospecials % ❺
\immediate\write\ans@out{\string\preans} % ❻
\immediate\write\ans@out{\string\par\string\noindent
{\string\sc\space Exercise\string~\thequestion.}\quad}% ❻
\immediate\write\ans@out{\string\vadjust{\string\nobreak}\relax} % ❼
\catcode`\^^M\active % ❺
\def\verbatim@processline{% ❺
\immediate\write\ans@out
{\the\verbatim@line}}%
\verbatim@start}
\def\endanswer{%
\immediate\write\ans@out{}% ❽
\@esphack} % ❹
\def\preans{\if@nobreak\global\@nobreakfalse\else\bigfilbreak\fi} % ❾
\def\printanswers{\immediate\closeout\ans@out % ❿
@input{\jobname.ans} % ⓫
}
The hard work I defer to the package verbatim ❶ which lets me create verbatim-like environments which will have special handling for their contents. Here I use some code shamelessly stolen ❺ from the documentation for that package (do texdoc verbatim for more details) to tell LaTeX to write everything between \begin{answer} and \end{answer} to an external file.
The external file part is handled via TeX's write facilities. I created a new writer ❷, created a macro to open the file which was called as part of the definition of \chapter ❸ since I was outputting answers at the end of each chapter rather than at the end of the book¹ but in your case you might want to replace that line with
\immediate\openout\ans@out=\jobname.ans
so that the file is created right away. The \@bsphack…\@esphack ❹ is probably not necessary here but it essentially tells LaTeX that this is code that isn't generating any output where it's called so that it's invisible space-wise. I wrote this code over 20 years ago, so I don't remember exactly what motivated that.²
I was lazy so I just output the code for formatting answers directly here ❻. If I were doing this today, I'd probably have it write instead something like \string\begin{theanswer}{\thequestion} before the output and \string\end{theanswer} afterwards. Prefixing \string to a macro is a primitive way of preventing expansion of the macro on write. Now, there are more robust ways to manage this, but again, you’re getting cut-and-pasted 20th century code here.
I think that at ❼ I was making sure that I didn't get a page break between the question number label and any displayed text that followed. At ❽ I was putting a blank line at the end of the question.³
The \preans code ❾ is something I stole from Knuth’s webmac.tex which will only break an answer across page boundaries if it’s longer than a page itself. It can make things look a bit nicer at the price of adding page count.
Finally, when it's time to print the answers, you close the \write ❿ and then read the generated file ⓫.
- It's always felt a little hostile to me to make readers flip so far to see the solutions to answers.
- Probably cargo culting.
- “You gotta make the back of the fence—that nobody will see— just as good looking as the front of the fence. Even though nobody will see it, you will know, and that will show that you’re dedicated to making something perfect.” –Paul Jobs