在新环境中使用 apptocmd

在新环境中使用 apptocmd

我尝试制作一份包含考试和相关更正的文档。我希望从问题到相关答案的自动超链接,反之亦然。

使用 Gonzalo Medina 给出的解决方案来回答问题自动标记枚举项,我能够自动标记不同的项目,并使用setlist我可以生成必要的超链接。

然而,我需要我的问题被标记qu:1,或者q:2.a相关答案也被标记rep:1,或者rep:2.a

Gonzalo Medina 的解决方案是使用类似的东西:

\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

它运行良好,但apptocmd肯定会改变 的定义\@item。不幸的是,在编写问题的解决方案时,我需要重新定义,\@item以便解决方案将标记为rep而不是qu

以下 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}

主要的不便之处在于,在问题的开始和答案的开始,我需要手动重新定义\item(并使用\setlist)的效果。

我想创建两个不同的环境,分别名为subjectsolutions(而且,这似乎与的本地效果兼容apptocmd)。

因此我尝试了以下方法:

\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}

然而,这根本不起作用:标签根本没有创建,itemitem每次使用两个新创建的环境之一时都会自动打印。为什么\apptocmdinside\newenvironment是个问题?(这就是问题所在吗?)。

答案1

我不知道有多少情况(实际上没有)\makeatletter...\makeatother宏内部是有用的。在这种情况下,它会阻止正确扩展\@item等宏,并\apptocmd应用于\item等。

\documentclass{book}
\usepackage{enumitem}
\usepackage{etoolbox}
\usepackage[colorlinks]{hyperref}

\makeatletter

\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*}
  \apptocmd{\@item}{%
    \ifnum\@enumdepth=1\relax
      \label{qu:\arabic{enumi}}
    \else 
    \ifnum\@enumdepth=2\relax
      \label{qu:\arabic{enumi}.\alph{enumii}}
  \fi\fi}{}{}
}{}

\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*}
  \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}

相关内容