\nameref 使用“未扩展”的文本?

\nameref 使用“未扩展”的文本?

假设我定义一个自定义命令\exercise如下。

\newcounter{exercise}
\newcommand\exercise{%
    \refstepcounter{exercise}%
    \section*{Exercise \theexercise}%
}

现在,在下面的例子中,我想\namerefhyperref包中使用。

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \nameref{ex:first}

\exercise\label{ex:third}
bar

这样会生成“参见练习 2”而不是“参见练习 1”。似乎使用了“未展开”文本,将其展开为当前计数器值。我如何确保\nameref{ex:first}生成“练习 1”?

(当然,我也可以直接使用Exercise~\ref{ex:first},但是这样更容易出错。而且,将来,我可能想用“问题”替换“练习”,而不必在文档中查找并替换所有出现的单词。)


完整示例:

\documentclass{article}

\usepackage{hyperref}

\newcounter{exercise}
\newcommand\exercise{%
    \refstepcounter{exercise}%
    \section*{Exercise \theexercise}%
}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \nameref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

答案1

确实,您需要传递的扩展\theexercise,因为hyperref不会对标题执行此操作。

\documentclass{article}
\usepackage{hyperref}

\newcounter{exercise}
\newcommand\exercise{%
  \par % just in case
  \refstepcounter{exercise}%
  \begingroup\edef\x{\endgroup
    \noexpand\section*{\unexpanded{Exercise} \theexercise}%
  }\x
}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \nameref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

这是该文件的(删节版)内容.aux

\newlabel{ex:first}{{1}{1}{Exercise 1}{section*.1}{}}
\newlabel{ex:second}{{2}{1}{Exercise 2}{section*.2}{}}
\newlabel{ex:third}{{3}{1}{Exercise 3}{section*.3}{}}

它是

\newlabel{ex:first}{{1}{1}{Exercise \theexercise }{section*.1}{}}
\newlabel{ex:second}{{2}{1}{Exercise \theexercise }{section*.2}{}}
\newlabel{ex:third}{{3}{1}{Exercise \theexercise }{section*.3}{}}

用你的代码。

笔记。为什么\unexpanded{Exercise}?在特殊情况下显然没有必要,但对于德语“Übung”来说却是必要的。


您也可以改用cleveref

\documentclass{article}
\usepackage{hyperref}
\usepackage[nameinlink]{cleveref}

\newcounter{exercise}
\newcommand\exercise{%
  \par % just in case
  \refstepcounter{exercise}%
  \section*{Exercise \theexercise}
}
\crefname{exercise}{Exercise}{Exercises}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \cref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

两种情况下的输出是相同的。

在此处输入图片描述

我们能避免这个\edef\x{\endgroup诡计吗?当然可以。

\documentclass{article}
%\usepackage{xparse} % not needed for LaTeX 2020-10-01 or later
\usepackage{hyperref}
\usepackage[nameinlink]{cleveref}

\ExplSyntaxOn
\NewDocumentCommand{\exercise}{}
 {
  \gooz_exercise:ne { \exercisename } { \theexercise }
 }
\cs_new_protected:Nn \gooz_exercise:nn
 {
  \par % just in case
  \refstepcounter{exercise}
  \section*{#1~#2}
 }
\cs_generate_variant:Nn \gooz_exercise:nn { ne }
\ExplSyntaxOff

\newcommand{\exercisename}{Exercise}
\newcounter{exercise}
\crefname{exercise}{\exercisename}{\exercisename s}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \cref{ex:first} or \nameref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

请注意,这cleveref不是必需的,如果您愿意,只需删除相关调用即可\nameref

相关内容