我正在尝试创建一个包含数学练习的文档,每个数学练习都会给出一个或多个提示,这些提示应该在后面的部分中显示。从插入的提示中应该可以跳回到匹配的问题。当我尝试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}