I am doing a follow up on How to expand a macro to use it inside a question in AMC?, as suggested by @Steven B. Segletes, so the question can be answered.
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.
Problem
But, I found problematic to create a \newbox
per question and insert it by hand. However, this is partially solved by two solutions:
One suggests to use named boxes using the same string as the question (which helps retrieving them automatically in the
\insertbox
command. However, it is hard to maintain as it needs a modification of several places when changing the ID of the question. Also, it doesn't allow me to have several boxes on the same questions (not sure if that is important now, but it may be good idea to have a more robust solution).Another one uses an auto increment in the boxes numbering, which is nice. However, when the questions are shuffled the number in the question is not the same as the order in which the boxes where declared (thus not retrieving the same box).
What I will like is to have the best of both worlds: an easy way to maintain the questions and preferably an automatic (transparent) way of naming then to the user, but that the questions remained coupled with their respective boxes when shuffled.
For example, the image below shows how the codes are shown in order as they were declared, but when the questions are shuffled, they may not appear in the same order.
\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
}
\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}? (question of \texttt{a+10})
\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}? (question of \texttt{a++})
\insertbox
\begin{choices}
\correctchoice{10}
\wrongchoice{11}
\wrongchoice{12}
\wrongchoice{0}
\end{choices}
\end{question}
}
%%% copies
\AMCrandomseed{123456789}
\onecopy{1}{
\cleargroup{all}
\setcounter{myboxcounter}{0}
\copygroup{code}{all}
\shufflegroup{all}
\insertgroup{all}
}
\end{document}