# Context

I'm trying to use AMC to produce an exam with code in it.

However, the use of verbatim code inside the questions is beyond the scope of the package. They suggest to declare boxes and used them inside each question. But, I found problematic to create a \newbox per question and insert it by hand.

Thus, I searched for a solution on how to create and insert boxes automatically (following this question and this answer).

# Problem

But now, I'm stuck with the expansion of the macros. As the macro I'm using inserts always the last created box. As it seems that the AMC package post processes all the elements (questions) in the \onecopy macro, and it expands my macro \insertbox then. However, I need to insert the expanded version of the macro in every element, in order to insert the expanded name of the box I created.

Thus, how can I expand the definition of the box and insert it in each question?

I tried to store the \savebox definition in another macro an insert it after, using \edef but that doesn't work either.

I will like to redefine \insertbox in such a way that is expanded with the name of the temporal box I created, instead of being expanded until the call of \onecopy.

# Code

\documentclass{article}

\usepackage[box]{automultiplechoice}
\usepackage{listings}

% a simple wrapper to create boxes automatically
\makeatletter
\newcounter{myboxcounter}
\newenvironment{mybox}{%
\expandafter\newsavebox\csname foobox\roman{myboxcounter}\endcsname
\global\expandafter\setbox\csname foobox\roman{myboxcounter}\endcsname\hbox\bgroup\color@setgroup\ignorespaces
}{%
\color@endgroup\egroup
}
% first try
% \newcommand{\insertbox}{\expandafter\usebox\csname\name\endcsname}
% second one
\newcommand{\insertbox}{\edef\name{foobox\roman{myboxcounter}}\edef\x{\expandafter\usebox\csname\name\endcsname}\x}
\makeatother

\begin{document}

%%% preparation of the groups
\begin{mybox}
\begin{lstlisting}[language=C++]
int a = 10;
a = a + 10;
\end{lstlisting}
\end{mybox}
\element{code}{
\begin{question}{code 1}
Which is the result of \texttt{a}?

\insertbox
\begin{choices}
\correctchoice{10}
\wrongchoice{20}
\wrongchoice{0}
\wrongchoice{30}
\end{choices}
\end{question}
}

\begin{mybox}
\begin{lstlisting}[language=C++]
int a = 10;
a = a++;
\end{lstlisting}
\end{mybox}
\element{code}{
\begin{question}{code 2}
Which is the result of \texttt{a}?

\insertbox
\begin{choices}
\correctchoice{10}
\wrongchoice{11}
\wrongchoice{12}
\wrongchoice{0}
\end{choices}
\end{question}
}

%%% copies
\onecopy{1}{
\insertgroup{code}
}

\end{document}


As you can see in the image below, both inserted codes belong to the last box created. As the macro seems to expand later, instead of when called in the \element macro.

Here, I reset the counter to 0 before the final \onecopy and redefine \insertbox to step the counter with its output.

\documentclass{article}

\usepackage[box]{automultiplechoice}
\usepackage{listings}

% a simple wrapper to create boxes automatically
\makeatletter
\newcounter{myboxcounter}
\newenvironment{mybox}{%
\stepcounter{myboxcounter}%
\expandafter\newsavebox\csname foobox\roman{myboxcounter}\endcsname
\global\expandafter\setbox\csname foobox\roman{myboxcounter}\endcsname\hbox\bgroup\color@setgroup\ignorespaces
}{%
\color@endgroup\egroup
}
% first try
% \newcommand{\insertbox}{\expandafter\usebox\csname\name\endcsname}
% second one
\newcommand{\insertbox}{\stepcounter{myboxcounter}%
\edef\name{foobox\roman{myboxcounter}}\edef\x{%
\expandafter\usebox\csname\name\endcsname}\x}
\makeatother

\begin{document}

%%% preparation of the groups
\begin{mybox}
\begin{lstlisting}[language=C++]
int a = 10;
a = a + 10;
\end{lstlisting}
\end{mybox}
\element{code}{
\begin{question}{code 1}
Which is the result of \texttt{a}?

\insertbox
\begin{choices}
\correctchoice{10}
\wrongchoice{20}
\wrongchoice{0}
\wrongchoice{30}
\end{choices}
\end{question}
}

\begin{mybox}
\begin{lstlisting}[language=C++]
int a = 10;
a = a++;
\end{lstlisting}
\end{mybox}
\element{code}{
\begin{question}{code 2}
Which is the result of \texttt{a}?

\insertbox
\begin{choices}
\correctchoice{10}
\wrongchoice{11}
\wrongchoice{12}
\wrongchoice{0}
\end{choices}
\end{question}
}

%%% copies
\setcounter{myboxcounter}{0}
\onecopy{1}{
\insertgroup{code}
}

\end{document}


• That is a nice workaround. However, if I use the functionality of AMC to shuffle the questions I will have problems, as the questions are not necessarily in the same order as they were input in the text.
Aug 5, 2014 at 20:19
• @adn True enough. But I don't have a (workaround)^2 yet... Aug 5, 2014 at 20:29
• any workaround yet?
Mar 30, 2015 at 1:25
• @adn I'm sorry, but I would have to know a lot more about how the shuffle operation of automultiplechoice operates, in order to even have an idea. Unfortunately, I have not tried to get to the bottom of that. Perhaps you could compose an MWE that makes use of the shuffle (showing the problem of renumbering) and ask it as a new question? Mar 30, 2015 at 2:31

I'm afraid you have to name the boxes, so that they can be retrieved in the right order. You can use the question ID as a name for the boxes:

\documentclass{article}

\usepackage[box]{automultiplechoice}
\usepackage{listings}

% a simple wrapper to create boxes automatically
\makeatletter
\newenvironment{mybox}[1]{%
\expandafter\newsavebox\csname foobox#1\endcsname
\global\expandafter\setbox\csname foobox#1\endcsname\hbox\bgroup\color@setgroup\ignorespaces
}{%
\color@endgroup\egroup
}
\newcommand{\insertbox}{\edef\name{foobox\AMCid@name}\edef\x{\expandafter\usebox\csname\name\endcsname}\x}
\makeatother

\begin{document}

%%% preparation of the groups
\begin{mybox}{code 1}
\begin{lstlisting}[language=C++]
int a = 10;
a = a + 10;
\end{lstlisting}
\end{mybox}
\element{code}{
\begin{question}{code 1}
Which is the result of \texttt{a}?

\insertbox
\begin{choices}
\correctchoice{10}
\wrongchoice{20}
\wrongchoice{0}
\wrongchoice{30}
\end{choices}
\end{question}
}

\begin{mybox}{code 2}
\begin{lstlisting}[language=C++]
int a = 10;
a = a++;
\end{lstlisting}
\end{mybox}
\element{code}{
\begin{question}{code 2}
Which is the result of \texttt{a}?

\insertbox
\begin{choices}
\correctchoice{10}
\wrongchoice{11}
\wrongchoice{12}
\wrongchoice{0}
\end{choices}
\end{question}
}

%%% copies
\onecopy{5}{
\shufflegroup{code}
\insertgroup{code}
}

\end{document}