背景(简化)
我正在使用todonotes 包nameref
将待办事项添加到我的文档中的部分。我创建了一个宏来将待办事项添加到部分,以便它们出现在目录中部分条目的旁边。我还使用hyperref 包通过名称引用文档中的各个部分。部分原因是,我的宏还允许为该部分指定标签。以下是我的宏生成的输出的一个略微简化的版本:
\section[{\todo{A todonote about the foo section}}{foo}]{foo}%
\label{sec:foo}
问题
问题在于,当使用\nameref
来引用标题中包含 todonote 的部分时(如上所述),todonote 也会附加到引用中。
梅威瑟:
\documentclass{article}
\usepackage{todonotes}
\usepackage[colorlinks,linkcolor=blue]{hyperref}
\begin{document}
\tableofcontents
\section{foo}
\begin{itemize}
\item A reference to the \nameref{sec:bar} section
\end{itemize}
\section[{\todo{A todonote about the bar section}}{bar}]{bar}
\label{sec:bar}
A section called bar
\section{baz}
A section called baz
\end{document}
其结果(经过三到四次编译/构建后)如下:
发生了什么:
因此,对的调用\nameref{sec:bar}
可能生成了一个包含{\todo{A todonote about the bar section}}{bar}
todonotes 的引用,因此 (正确但不可取) 生成了重复的 todonote。澄清一下,我希望对 bar 部分的引用生成为 just,bar
而不生成重复的 todonote。
寻找解决方案的方法
虽然这是我的用例,但我更愿意知道如何nameref
忽略部分标题内的任何命令,因为我觉得这可能更普遍有用(而不仅仅是对我而言)。
顺便提一下,忽略命令的另一种解决方案可能是以nameref
某种方式为该部分定义一些特定的参考文本。但是,这并不理想,因为它需要一点维护才能使其与部分名称保持相关。
答案1
Stefan Lehmke 解决方案的简化版本:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{todonotes}
\usepackage[colorlinks,linkcolor=blue]{hyperref}
\makeatletter
\newcommand\@namedisablecommands{}
\newcommand{\addnamedisablecommand}[1]{%
\g@addto@macro\@namedisablecommands{\renewcommand#1{}}%
\pdfstringdefDisableCommands{\renewcommand#1{}}%
}
\AtBeginDocument{
\patchcmd{\T@nameref}
{\let\label\@gobble}
{\let\label\@gobble\@namedisablecommands}
{}{}
}
\makeatother
\addnamedisablecommand{\todo[2][]}
注意改变的语法;为了保持 Stefan 的写入
\newcommand{\addnamedisablecommand}[2]{%
\g@addto@macro\@namedisablecommands{\renewcommand#1#2{}}%
\pdfstringdefDisableCommands{\renewcommand#1#2{}}%
}
反而。
完成此操作后,\@namedisablecommands
将扩展为
\renewcommand\todo[2][]{}
这将抵消其扩张。警告
Package hyperref Warning: Token not allowed in a PDF string (PDFDocEncoding):
(hyperref) removing `\todo' on input line 47.
\todo
可以通过在 的禁用命令列表中添加 (或其他类似命令)来避免hyperref
。
答案2
有趣的是,\nameref
似乎知道有些东西应该被禁用(例如\label
),但它没有提供用于调整它的界面。
因此,修补似乎是一个解决方案。我重复一下完整的例子:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{todonotes}
\usepackage[colorlinks,linkcolor=blue]{hyperref}
\makeatletter
\newcommand\@namedisablecommands{}%
\newcount\@namedisablegenericmacro
\newcommand\addnamedisablecommand[2]
{%
\global\advance\@namedisablegenericmacro\@ne
\expandafter\newcommand
\csname @namedisablegobble\number\@namedisablegenericmacro\endcsname
#2{}%
\global\expandafter\let
\csname @namedisablegobble\number\@namedisablegenericmacro\expandafter\endcsname
\csname @namedisablegobble\number\@namedisablegenericmacro\endcsname
\edef\@namedisablecommands{%
\unexpanded\expandafter{\@namedisablecommands}%
\let\noexpand#1\expandafter\noexpand
\csname @namedisablegobble\number\@namedisablegenericmacro\endcsname
}%
}
\AtBeginDocument
{%
\patchcmd{\T@nameref}
{\let\label\@gobble}
{\let\label\@gobble\@namedisablecommands}
{}{}%
}
\addnamedisablecommand{\todo}{[2][]}
\expandafter\pdfstringdefDisableCommands\expandafter
{%
\@namedisablecommands
}%
\makeatother
\begin{document}
\tableofcontents
\section{foo}
\begin{itemize}
\item A reference to the \nameref{sec:bar} section
\end{itemize}
\section[{\todo{A todonote about the bar section}}{bar}]{bar}
\label{sec:bar}
A section called bar
\section{baz}
A section called baz
\end{document}