![如何对编号部分进行超目标定位?](https://linux22.com/image/236786/%E5%A6%82%E4%BD%95%E5%AF%B9%E7%BC%96%E5%8F%B7%E9%83%A8%E5%88%86%E8%BF%9B%E8%A1%8C%E8%B6%85%E7%9B%AE%E6%A0%87%E5%AE%9A%E4%BD%8D%EF%BC%9F.png)
我想要\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}{}}