如何对编号部分进行超目标定位?

如何对编号部分进行超目标定位?

我想要\hypertarget一些我的部分。我知道我可以将\label它们或超目标放在它们之前,但这是一个更大的框架的一部分,我不想以不同的方式处理目标恰好是章节标题的情况。这是我的最小示例,它适用于\section*但不能适用于\section。为什么?

\documentclass[a4paper,12pt]{article}
\usepackage[pdfstartview=FitH]{hyperref}
\usepackage{bookmark}
\begin{document}

\section*{one\hypertarget{sec:one}{}}
\bookmark[dest=sec:one]{sec one}

\section{two\hypertarget{sec:two}{}}
\bookmark[dest=sec:two]{sec two}

\end{document}

附言:太棒了,超目标和部分都不是有效的标签。请有人在其中插入一些有用的东西。

编辑:结合\texorpdfstring上述最小示例可以工作,但通常它太过简单,我的生产代码无法编译。我创建了一个更接近实际用途的最小示例,它创建了一个正确的文件,但有很多错误消息,使用宏的undefined control sequence行上可怕的匿名。我该如何调试此错误消息?有人能告诉我代码有什么问题吗?

\documentclass[a4paper,12pt]{article}
\usepackage{amsmath}
\usepackage[pdfstartview=FitH]{hyperref}
\usepackage[atend]{bookmark}
\newcounter{nops}
\makeatletter
\newcommand{\nopimpl}{\stepcounter{nops}\Hy@raisedlink{\hypertarget{nop\arabic{nops}}{}}\begingroup\edef\x{\endgroup\noexpand\BookmarkAtEnd{\noexpand\bookmark[dest=nop\arabic{nops}]{page \arabic{nops}}}}\x}
\newcommand{\nop}{\texorpdfstring{\iffirstchoice@\nopimpl\fi}{}}
\makeatother
\begin{document}

\section{one\nop}
\section{two\nop}

\end{document}

编辑2:再次感谢。现在这些错误已经消失,但在实际文件中有一个目录,并且目录项有自己的目标。我该如何防止这种情况发生?

另外,为什么鲁棒性仅仅是一个声明的问题?我认为它应该是要执行的代码的属性。如果我可以简单地声明东西是鲁棒的,为什么 Latex 不能使所有东西都变得鲁棒?

\documentclass[a4paper,12pt]{article}
\usepackage{amsmath}
\usepackage[pdfstartview=FitH]{hyperref}
\usepackage[atend]{bookmark}
\newcounter{nops}
\makeatletter
\DeclareRobustCommand{\nopimpl}{\stepcounter{nops}\Hy@raisedlink{\hypertarget{nop\arabic{nops}}{}}\begingroup\edef\x{\endgroup\noexpand\BookmarkAtEnd{\noexpand\bookmark[dest=nop\arabic{nops}]{page \arabic{nops}}}}\x}
\DeclareRobustCommand{\nop}{\texorpdfstring{\iffirstchoice@\nopimpl\fi}{}}
\makeatother
\begin{document}
\tableofcontents
\section{one\nop}
\section{two\nop}
\end{document}

答案1

普通分段宏的内容如下,\section称为移动论点因为它也从其正常位置移动到其他地方,即目录和 PDF 书签侧栏。为此,它会被写入一些辅助文件(.aux.out)并在此过程中被扩展。只有强壮的不介意在这里扩展工作的宏和其他脆弱的宏必须放置\protect在它们前面以进行保护。此外,PDF 书签中不允许使用某些材料(例如某些数学符号)。该hyperref包提供了\texorpdfstring{<tex>}{<pdf>}可用于为文档和 PDF 书签选择不同文本的选项。因此,您可以使用\section{two\texorpdfstring{\protect\hypertarget{sec:two}{}}{}}仅在文档中使用\hypertarget,而不在 PDF 书签中使用,因为这样做没有意义。另一个选项是使用可选参数\section为 ToC 和 PDF 书签提供替代文本。

\documentclass[a4paper,12pt]{article}
\usepackage[pdfstartview=FitH]{hyperref}
\usepackage{bookmark}
\begin{document}

\section*{one\hypertarget{sec:one}{}}
\bookmark[dest=sec:one]{sec one}

\section{two\texorpdfstring{\protect\hypertarget{sec:two}{}}{}}
\bookmark[dest=sec:two]{sec two}

\section[three]{three\hypertarget{sec:three}{}}
\bookmark[dest=sec:three]{sec three}

\end{document}

回答您更新后的答案:
如上所述,移动参数中使用的所有宏都必须是健壮的,以免造成麻烦。这可以通过\protect在其前面使用来实现,即 或通过从一开始就使用而不是来\section{one\protect\nop}定义健壮。一个问题是也将在 ToC 中使用,因此您应该首先将其定义为空,然后在之后重新定义它。您可以使用将定义代码添加到此宏中。\nop\DeclareRobustCommand\newcommand\nop\nop\tableofcontents\g@addto@macro

\documentclass[a4paper,12pt]{article}
\usepackage{amsmath}
\usepackage[pdfstartview=FitH]{hyperref}
\usepackage[atend]{bookmark}
\newcounter{nops}
\makeatletter
\DeclareRobustCommand{\nopimpl}{\stepcounter{nops}\Hy@raisedlink{\hypertarget{nop\arabic{nops}}{}}\begingroup\edef\x{\endgroup\noexpand\BookmarkAtEnd{\noexpand\bookmark[dest=nop\arabic{nops}]{page \arabic{nops}}}}\x}
\newcommand{\nop}{}
\g@addto@macro{\tableofcontents}{\DeclareRobustCommand{\nop}{\texorpdfstring{\iffirstchoice@\nopimpl\fi}{}}}

\makeatother
\begin{document}
\tableofcontents

\section{one\nop}
\section{two\nop}

\end{document}

您也可以定义一些宏\mysection[2]{\section[#1]{#1#2}并像 一样使用它\mysection{section text}{\nop}。这样可以避免一些麻烦。

答案2

试试这个: \section[two]{two\hypertarget{sec:two}{}}

相关内容