保护设置 \@currentlabelname 为 \phantomsection 赋予“名称”

保护设置 \@currentlabelname 为 \phantomsection 赋予“名称”

这是nameref 带有任意文本并且引用任意文本(不带编号且不按章节)

总而言之,问题是关于如何使用任意字符串引用文本中的任意点;而流行的解决方案是使用

previousText 
\phantomsection 
\label{L} 
textToBeReferenced 
[...] 
\hyperref[L]{textPointingToReference}

在这些问题中,作者满足于在插入引用的位置定义 textPointingToReference,但在我的用例中,我确实需要textPointingToReference在创建标签时定义字符串(或者 \nameref 的输出,如果你愿意的话)。

这是因为我想从文档中的多个点访问引用对象的名称,如果我使用,\hyperref[ObjectLabel]{ObjectNameExplicitlyGiven}我将需要编辑\hyperref对象名称发生变化的所有实例。

我在调用时读取了存储在 aux 文件中的nameref文档。 的使用与 的值无关,因此我天真地尝试手动设置,如下所示:\@currentlabelname\label\phantomsection\@currentlabelname\@currentlabelname

\documentclass{article}

\usepackage{hyperref}

%% outputs an object (in fact, a music score, that is a paragraph for TeX purposes) with label
\newcommand{\insertobject}[2]{
  %% #1 : reference of the object
  %% #2 : name of the object
  \makeatletter\edef\@currentlabelname{#2}\makeatother
  \phantomsection
  \label{#1}
  %% the objects I work with are music scores but this is irrelevant
  %% the commented line below would fetch and insert a music file named #1
  %\insert_music_score{#1}
  Object with reference #1 is here
}

%% Macro to print a cross-reference to an object
\newcommand{\objectreference}[1]{
    See object \nameref{#1}, page \pageref{#1}%
}

\begin{document}

\section{Section Title}

Lorem Ipsum

\insertobject{XYZ}{Object XYZ Name}

\objectreference{XYZ}

\end{document}

当然,这没有任何作用,\@currentlabelname因为写入\label辅助文件的仍然是“部分标题”而不是“对象 XYZ 名称”:

在此处输入图片描述

但是后来,我尝试将代码替换\insertobject到文档中,瞧,它起作用了:

\documentclass{article}

\usepackage{hyperref}

%% Macro to print a cross-reference to an object
\newcommand{\objectreference}[1]{
    See object \nameref{#1}, page \pageref{#1}%
}

\begin{document}

\section{Section Title}

Lorem Ipsum

  \makeatletter\edef\@currentlabelname{Object XYZ Name}\makeatother
  \phantomsection
  \label{XYZ}
  Object with reference XYZ is here

\objectreference{XYZ}

\end{document}

在此处输入图片描述

然后我读\@currentlabelname 和自定义计数器并且,由于对保护一无所知,我尝试用 替换 定义中的那一行,\insertobject然后\makeatletter\protected@edef\@currentlabelname{#2}\makeatother保护对 的调用\insertobject,但它只是给了我经典的“不能使用带有字符 @ 的前缀”错误。

有什么想法可以实现这一点吗?

答案1

由@Ulrike Fischer 在评论中解决:“\makeatletter/\makeatother 必须位于 \newcommand 外面/周围。”

以下 MWE 产生预期的输出(问题中的第二张图片):

\documentclass{article}

\usepackage{hyperref}

%% outputs an object (in fact, a music score, that is a paragraph for TeX purposes) with label
\makeatletter
\newcommand{\insertobject}[2]{
  %% #1 : reference of the object
  %% #2 : name of the object
  \protected@edef\@currentlabelname{#2}
  \phantomsection
  \label{#1}
  %% the objects I work with are music scores but this is irrelevant
  %% the commented line below would fetch and insert a music file named #1
  %\insert_music_score{#1}
  Object with reference #1 is here
}
\makeatother

%% Macro to print a cross-reference to an object
\newcommand{\objectreference}[1]{
    See object \nameref{#1}, page \pageref{#1}%
}

\begin{document}

\section{Section Title}

Lorem Ipsum

\insertobject{XYZ}{Object XYZ Name}

\objectreference{XYZ}

\end{document}

相关内容