0

I’ve got a problem renewing a command inside an enumerate environment.

I wish to make some exercises and to append the solution of each exercise to a predefined macro called “solutions”.

Adding solutions works fine as long as I do it outside the \begin{enumerate} \end{enumerate}, but adding solutions to this macro fails when it is done inside this environment.

Any help will be appreciated, I’ve been searching for a solutions on the internet but didn’t succeed. Thank you very much!

Here is the minimal working example. I tried it with \newcommand as well as \def.

\documentclass[12pt,a4paper]{report}

\usepackage[french]{babel}
\usepackage{fontspec} 
\usepackage{xunicode}

\newcommand{\solutions}{First}

\newcommand{\addsol}[1]{%
    \expandafter\renewcommand\expandafter\solutions\expandafter{\solutions,#1}%
    }

%\def\solutions{First}
%\def\addsol#1{%
%   \expandafter\def\expandafter\solutions\expandafter{\solutions,#1}%
%   }

\begin{document}

\addsol{Second}

\begin{enumerate}
    \item Lorem Ipsum \addsol{Third}

\end{enumerate}

% Print the contents of solutions

\solutions

\end{document}

In each case I obtain the following output, meaning that the first and second appending worked, but the third failed:

  1. Lorem Ipsum

First,Second

2 Answers 2

1

You need \gdef, because environments form groups.

\documentclass[12pt,a4paper]{report}

\usepackage[french]{babel}
\usepackage{fontspec} 
%\usepackage{xunicode}% <--- not recommended


\newcommand{\addsol}[1]{%
  \ifdefined\solutions
    \expandafter\gdef\expandafter\solutions\expandafter{\solutions,#1}%
  \else
    \gdef\solutions{#1}%
  \fi
}

\begin{document}

\addsol{First}
\addsol{Second}

\begin{enumerate}
    \item Lorem Ipsum \addsol{Third}

\end{enumerate}

% Print the contents of solutions

\solutions

\end{document}

Note that xunicode used to be recommended a few years ago, but it isn't nowadays.

On the other hand, there's a better method with expl3, that allows to print solutions in a variety of ways. The \printsolutions command has an optional argument that tell TeX what to put in between two solutions, default “comma-space”.

\documentclass[12pt,a4paper]{report}

\usepackage[french]{babel}
\usepackage{fontspec} 

\ExplSyntaxOn

\seq_new:N \g_ladi_solutions_seq

\NewDocumentCommand{\addsol}{m}
 {
  \seq_gput_right:Nn \g_ladi_solutions_seq { #1 }
 }
\NewDocumentCommand{\printsolutions}{+O{,~}}
 {
  \seq_use:Nn \g_ladi_solutions_seq { #1 }
 }

\ExplSyntaxOff

\begin{document}

\addsol{First}
\addsol{Second}

\begin{enumerate}
    \item Lorem Ipsum \addsol{Third}
\end{enumerate}

% Print the contents of solutions with commas

\section*{Solutions}

\printsolutions

\section*{Solutions}

\printsolutions[\par]

\end{document}

enter image description here

2
  • The \gdef solution you proposed works exactly like I wanted, and I fully understand it, so really thanks for that, it solved my problem! I have a connected issue to complete this macro, it’s about the automatic numbering of the solutions by attributing the label of the current item to each answer. Something like \expandafter\gdef\expandafter\solutions\expandafter{\solutions, « label of the current item » #1}% I tried using, for example, \Alph{enumi} but it gave me the final value of enumi after the enumerate group finished. Maybe I’ll make a new post to better explain this issue.
    – ladi
    Jul 8, 2023 at 6:07
  • As for the other method, I’ll give it a try after being familiar with this expl3 package, completely new to me.
    – ladi
    Jul 8, 2023 at 6:14
2

LaTeX's environments are groups. If you change something inside the group in a non-global way, the former value will get restored after the \end{enumerate}.

Your macro \addsol{...} assigns the new content in a non-local way, but you want your changes done in a global way using \gdef instead of a simple \def.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .