12

There is a class for LaTeX called exam. Using this class, one can write questions and answers for exams. The answers are displayed under (after) each question. My goal is to have all answers in the separate part of the document (after all questions). For that purpose I tried to create new environment like this:

\newenvironment{answer}{\def\answertext\begingroup}{\endgroup}

I was hoping to gather answer text into \answertext and dump it after all questions. I'm sure, a solid TeX Package/Class writer can do it within no time... Please, give me some hint.

3 Answers 3

9

We accumulate all the answers in a \vbox, and then dump the contents out of the \vbox and onto the page when it's appropriate. (Thus, when the answers actually hit the page, they're not inside of the \vbox, and so there's no interference with pagebreaks.)

Here's a complete LaTeX file that demonstrates the idea:

\documentclass{exam}

\newbox\allanswers
\setbox\allanswers=\vbox{}

\newenvironment{answer}
{%
  \global\setbox\allanswers=\vbox\bgroup
  \unvbox\allanswers
}%
{%
  \bigbreak
  \egroup
}

\newcommand{\showallanswers}{\par\unvbox\allanswers}


%--------------------------------------------------------------------
\begin{document}

\begin{questions}
  \question Why is there air?

  \begin{answer}
    Answer to Question \thequestion:

    There's air so that we can blow up volleyballs and basketballs.
  \end{answer}

  \question Who's buried in Grant's tomb?
  \begin{answer}
    Answer to Question \thequestion:

    What's his name.
  \end{answer}

  \question What was the color of George Washington's white horse?
  \begin{answer}
    Answer to Question \thequestion:

    Blue.  (No; Yellow!!)
  \end{answer}
\end{questions}

\bigskip
\begin{center}
  Here are the answers:
\end{center}
\showallanswers







\end{document}
4
  • +1 This is great. Does the exam class have something built-in like this for multiple choice questions (using the choices environment), or should I use something like your answer?
    – cmhughes
    Nov 16, 2011 at 0:12
  • @cmhughes: Alas, no, this isn't part of the exam class,but you can just copy the code above into your LaTex file. Nov 16, 2011 at 2:04
  • I try Phil Hirschhorn's method, and I found that I can use the verbatim environment inside the answer environment, great! I will try to hook your solution environment in the exam class to see whether I can put all the answers together separately. Thanks.
    – ollydbg23
    Jan 8, 2015 at 3:51
  • Hi. This works great; I notice that when you print all the answers they don't have the problem number to which they correspond. I tried fixing this with etootlbox', but can't see to make it work: \AtBeginEnvironment{answer}{\vspace{\baselineskip}\thequestion\,} ` prints the counter just after the question (which makes a lot of sense), but I cannot figure out how to print that counter on the box you defined. Any ideas? Feb 25, 2020 at 5:31
3

The \def macro doesn't accept \begingroup...\endgroup instead of { }. No macro does. Some macros (like \hbox) accept \bgroup and \egroup which are implicit braces, i.e. created using \let\bgroup={ and \let\egroup=} (the = is optional).

To store the content of an environment use the environ package which was created for this purpose. The content is presented as \BODY which can be copied to \answertext. Keep in mind that the code is executed inside the environment, i.e. in a group, therefore \global\let\answertext\BODY or \xdef\answertext{\BODY} must be used. However, this only allows one answer text to be stored. If you want to accumulate answers use either \g@addto@macro<macro>{<code>}, e.g. \expandafter\g@addto@macro\expandafter\answertext\expandafter{\BODY} or the \xappto macro of the etoolbox package.

Some example (without the exam class):

\documentclass{article}

\usepackage{environ}

\newcommand{\answertext}{}
\NewEnviron{answer}{\global\let\answertext\BODY}
% or
\makeatletter
\NewEnviron{answer}{\expandafter\g@addto@macro\expandafter\answertext\expandafter{\BODY}}%
\makeatother
% or
\usepackage{etoolbox}
\NewEnviron{answer}{\xappto\answertext{\expandonce{\BODY}}}%


\begin{document}

The question
\begin{answer}
  The answer text
\end{answer}

\newpage
% Some time later
\answertext


\end{document}
4
  • I think the intention is also to add to \answertext (e.g. via \g@addto@macro)
    – Caramdir
    Apr 8, 2011 at 23:07
  • @Caramdir: Good point. I forgot to point out that this only works for one answer. I will add the use of \g@addto@macro. Apr 8, 2011 at 23:09
  • Hi, great answer. In my usage, I have some code snippets in the answers, so I use a verbatim environment inside the answer environment, but I get failed. I'm using the third way which use \xappto command which add the answer body to a macro definition. Are there any workaround about this issue. I know that verbatim environment is some kind of fragile, which means I can't move its body simply or pass its body as macro arguments. Thanks.
    – ollydbg23
    Jan 7, 2015 at 7:25
  • @ollydbg23: In your case it would be better to store the answer in a savebox and set this box later. Search for "savebox" to find some suitable solutions. However, this way the format of the answer is getting defined by the active format when it is stored not when it is placed, like in the case above. Jan 11, 2015 at 18:57
0

My file ans.sty at http://www.cwru.edu/artsci/math/wells/pub/mytex.html is old but I use it regularly to this day. It can no doubt be modified to do what you want.

You must log in to answer this question.