使用 expl3 在标记列表中包含引用

使用 expl3 在标记列表中包含引用

我正在尝试创建一个包含数学练习的文档,每个数学练习都会给出一个或多个提示,这些提示应该在后面的部分中显示。从插入的提示中应该可以跳回到匹配的问题。当我尝试ref在问题中插入一个时,LaTeX 给出了错误

! Argument of \@firstoftwo has an extra }

每个给出的提示都保存在一个全局标记列表中,并首先在文档末尾呈现。这个工作还不错,但我想从提示中包含一个指向练习的链接。我在代码中用 TODO 突出显示了我尝试的解决方案。

代码在本文末尾提供,渲染的输出显示如下:

渲染输出

\documentclass{article}
\usepackage{expl3}
\usepackage{hyperref}

\ExplSyntaxOn
\tl_new:N \g_allgivenhints_tl
\tl_new:N \l_temp_tl

\newcounter{exercise} 

% Define an environment for numbered exercises.
\NewDocumentEnvironment{exercise}{O{}+b}{
% Begin exercise
\refstepcounter{exercise}
\noindent
Exercise~\theexercise\par
\label{exercise\theexercise}
\noindent #2
}{
% End exercise
\medskip
}

% Define an environment for hints to exercises.
% All hints should be at the end of the document
% where the \showhints command is inserted.
\NewDocumentEnvironment{hint}{O{}+b}{%
\tl_gput_right:Nn \g_allgivenhints_tl { \par\noindent }
\tl_gput_right:Nx \g_allgivenhints_tl { Hint~for~exercise~\theexercise }
% TODO
% TODO
% TODO: The line below is what I think I want to do, but it fails ...
% TODO
% TODO
%\tl_gput_right:Nx \g_allgivenhints_tl { Hint~for~exercise~\theexercise \ref{exercise\theexercise{}} }
\tl_gput_right:Nn \g_allgivenhints_tl { \par\noindent }
\tl_gput_right:Nn \g_allgivenhints_tl { #2 }
\tl_gput_right:Nn \g_allgivenhints_tl { \medskip }
}{
% hint end
}

% Define a command that inserts all the given
% hints at that location.
\NewDocumentCommand{\showhints}{}{\tl_use:N \g_allgivenhints_tl}

\ExplSyntaxOff

\begin{document}
\section{Exercises}
\label{secExercise}

\begin{exercise}
Question in exercise one.
\begin{hint}
Hint for exercise one.
\end{hint}
\end{exercise}


\begin{exercise}
Question in exercise two.
\begin{hint}
Hint for exercise two.
\end{hint}
\end{exercise}



\section{Hints}
Manual reference to exercise one \ref{exercise1}.

\noindent
Manual reference to exercise two \ref{exercise2}.
\medskip

\showhints


\end{document}

答案1

您应该使用\exp_not:N \ref,以避免不合时宜的扩展。

不过,我会使用一种稍微不同的方法,带有一个序列。

\documentclass{article}
%\usepackage{xparse} % not needed with LaTeX 2020-10-01 or later
\usepackage{hyperref}

\newcounter{exercise} 

\ExplSyntaxOn

\seq_new:N \g_midtiby_hints_seq

% Define an environment for numbered exercises.
\NewDocumentEnvironment{exercise}{O{}}
 {
  % Begin exercise
  \par
  \addvspace{\medskipamount}
  \refstepcounter{exercise}\label{exercise\theexercise}
  \noindent
  Exercise~\theexercise\par\nobreak
  \noindent\ignorespaces
 }
 {
  % End exercise
  \par\addvspace{\medskipamount}
 }

% Define an environment for hints to exercises.
% All hints should be at the end of the document
% where the \showhints command is inserted.
\NewDocumentEnvironment{hint}{O{}+b}
 {
  \seq_gput_right:Nx \g_midtiby_hints_seq
   {
    \noindent Hint~for~exercise~\exp_not:N \ref{exercise\theexercise}
    \exp_not:n { \par\nobreak\noindent #2 }
   }
 }
 {
  % hint end
 }

% Define a command that inserts all the given
% hints at that location.
\NewDocumentCommand{\showhints}{}
 {
  \par\addvspace{\medskipamount}
  \seq_use:Nn \g_midtiby_hints_seq { \par\addvspace{\medskipamount} }
 }
\ExplSyntaxOff

\begin{document}

\begin{exercise}
This is easy.
\end{exercise}
\begin{hint}
No hint here.
\end{hint}

\begin{exercise}
This is easy again.
\end{exercise}
\begin{hint}
No hint here.
\end{hint}

\begin{exercise}
This is not easy.
\end{exercise}
\begin{hint}
A long hint here.
\end{hint}

\showhints

\end{document}

在此处输入图片描述

相关内容