I try to produce a document containing an exam and the associated correction. I want automatic hyperlinks from the question to the associated answer and vice-versa.
Using the solution given by Gonzalo Medina to the question Automatic labeling of enumeration items, I am able to label automatically the different item, and using setlist I can produce the necessary hyperlinks.
However, I need my questions to be label qu:1 or q:2.a ant the associated answers to be labeled rep:1 or rep:2.a
Gonzalo Medina's solution is to use something like that :
\makeatletter
\apptocmd{\@item}{
\ifnum\@enumdepth=1\relax
\label{qu:\arabic{enumi}}
\else
\ifnum\@enumdepth=2\relax
\label{qu:\arabic{enumi}.\alph{enumii}}
\fi\fi}{}{}
\makeatother
It works fine, but apptocmd definitely changes the definition of \@item. Unfortunately, when writing the solutions to the question, I will need to redefine \@item so that the solutions will be label with rep and not qu.
Something that seems to work but does not really satifies me is the following MWE :
\documentclass{book}
\usepackage{enumitem}
\usepackage{etoolbox}
\usepackage[colorlinks]{hyperref}
\setlist[enumerate,1]{label=\hyperref[rep:\arabic{enumi}]{\arabic*.}}
\setlist[enumerate,2]{label=\hyperref[rep:\arabic{enumi}.\alph{enumii}]{\arabic{enumi}.\alph*.},ref=\alph*}
\begin{document}
Questions :
\begin{enumerate}
\makeatletter
\apptocmd{\@item}{
\ifnum\@enumdepth=1\relax
\label{qu:\arabic{enumi}}
\else
\ifnum\@enumdepth=2\relax
\label{qu:\arabic{enumi}.\alph{enumii}}
\fi\fi}{}{}
\makeatother
\item A question
\begin{enumerate}
\item A subquestion
\item Another subquestion
\end{enumerate}
\item An other question
\end{enumerate}
\newpage
Solutions :
\setlist[enumerate,1]{label=\hyperref[qu:\arabic{enumi}]{\arabic*.}}
\setlist[enumerate,2]{label=\hyperref[qu:\arabic{enumi}.\alph{enumii}]{\arabic{enumi}.\alph*.},ref=\alph*}
\begin{enumerate}
\makeatletter
\apptocmd{\@item}{
\ifnum\@enumdepth=1\relax
\label{rep:\arabic{enumi}}
\else
\ifnum\@enumdepth=2\relax
\label{rep:\arabic{enumi}.\alph{enumii}}
\fi\fi}{}{}
\makeatother
\item An answer
\begin{enumerate}
\item A sub-answer
\item Another sub-answer
\end{enumerate}
\item Another answer
\end{enumerate}
\end{document}
The main inconvenient is that a the begin of the questions and the beginning of the answers, I need to manually redefine the effect of \item (and use \setlist).
I'd like to create two different environment, named subject and solutions (moreover, this seems compatible with the local effect of apptocmd).
So I tried the following :
\documentclass{book}
\usepackage{enumitem}
\usepackage{etoolbox}
\usepackage[colorlinks]{hyperref}
\newenvironment{subject}{
\setlist[enumerate,1]{label=\hyperref[rep:\arabic{enumi}]{\arabic*.}}
\setlist[enumerate,2]{label=\hyperref[rep:\arabic{enumi}.\alph{enumii}]{\arabic{enumi}.\alph*.},ref=\alph*}
\makeatletter
\apptocmd{\@item}{
\ifnum\@enumdepth=1\relax
\label{qu:\arabic{enumi}}
\else
\ifnum\@enumdepth=2\relax
\label{qu:\arabic{enumi}.\alph{enumii}}
\fi\fi}{}{}
\makeatother
}{}
\newenvironment{solution}{
\setlist[enumerate,1]{label=\hyperref[qu:\arabic{enumi}]{\arabic*.}}
\setlist[enumerate,2]{label=\hyperref[qu:\arabic{enumi}.\alph{enumii}]{\arabic{enumi}.\alph*.},ref=\alph*}
\makeatletter
\apptocmd{\@item}{
\ifnum\@enumdepth=1\relax
\label{rep:\arabic{enumi}}
\else
\ifnum\@enumdepth=2\relax
\label{rep:\arabic{enumi}.\alph{enumii}}
\fi\fi}{}{}
\makeatother
}{}
\begin{document}
Questions :
\begin{subject}
\begin{enumerate}
\item A question
\begin{enumerate}
\item A subquestion
\item Another subquestion
\end{enumerate}
\item An other question
\end{enumerate}
\end{subject}
\newpage
Solutions :
\begin{solution}
\begin{enumerate}
\item An answer
\begin{enumerate}
\item A sub-answer
\item Another sub-answer
\end{enumerate}
\item Another answer
\end{enumerate}
\end{solution}
\end{document}
However, this is not working at all : the labels are not created at all, and it automatically prints itemitem at each use of one of the two newly created environments. Why having \apptocmd inside \newenvironment is a problem ? (and is that THE problem ?).
\makeatletter...\makeatotheroutside of the environments ;-) – Jul 07 '15 at 16:06\makeatlettermust precede code that mentions commands with@in their name, not be inside code that uses them. SInce your\newenvironmentdefinition mentions\@item,\makeatlettermust be before\newenvironment. See http://tex.stackexchange.com/questions/8351/what-do-makeatletter-and-makeatother-do – egreg Jul 07 '15 at 16:17itemitemat each call of the environmentsubject? – mvienney Jul 07 '15 at 17:02