两个超链接指向同一个超目标。可能吗?

两个超链接指向同一个超目标。可能吗?

我需要在 latex 生成的 pdf 中创建指向单个目标的多个链接。Acrobat 支持此功能,但我不知道如何在 latex 中执行此操作。目标总是只返回一个链接,而其他链接不会转到目标。以下是带有屏幕截图的相关代码。

\par Mary had a little \hyperlink{s1}{\raisebox{\ht\strutbox}{\hypertarget{t1}{}}{lamb}}.\par 

\par Whose fleece was white as \hyperlink{s2}{\raisebox{\ht\strutbox}{\hypertarget{t1}{}}{snow}}.\par 

\par Wherever Mary went the lamb was \raisebox{\ht\strutbox}{\hypertarget{s2}}{}{\hyperlink{t1}{sure }}to go.

在此处输入图片描述

请注意,只有“snow”和“sure”链接有效,而“lamb”链接无效。任何建议都值得赞赏。

答案1

您的代码的第一行是\hyperlink{s1}{...}

这不起作用,因为在您的代码中该指令\hypertarget{s1}{...}没有出现在任何地方:

该命令\hyperlink{s1}{...}表示未定义/不存在的目标的名称/在 .pdf 文件中没有命名目的地=没有目标=没有锚点=没有“命名导航点”与之关联。


该宏\hypertarget用于创建命名目的地=目标=锚点。这样的东西基本上只是一个可以通过其名称引用的“命名导航点”。
该“命名导航点”放置在 TeX 在遇到/处理 -command 时即将构造的框的基线上\hypertarget
如果您在\hypertarget的第二个参数中提供文本,则“命名导航点”也是从该文本创建的第一个东西(框/胶水/字距/任何东西)的参考点。
但您可以将\hypertarget的第二个参数留空,这样根本不提供任何文本。
您需要做的就是确保“命名导航点”和它旁边的框之间没有断点,当导航到该命名目的地=目标=锚点=“命名导航点”时,您希望它的左上角位于 pdf 查看器显示窗口的左上角。

该宏\hyperlink用于在 pdf 文件中创建超链接,以便单击该链接会导致将表示为目标的“命名导航点”滚动到 pdf 查看器显示窗口的左上角。

让我们根据您提供的代码片段来看一个示例:

\documentclass[a4paper]{article}

\usepackage{hyperref}

\begin{document}

\par Mary had a little \hyperlink{s1}{\raisebox{\ht\strutbox}{\hypertarget{t1}{}}{lamb}}.\par

\newpage 

% Here the \hypertarget t1 is created once more instead of creating \hypertarget s1.
\par Whose fleece was white as \hyperlink{s2}{\raisebox{\ht\strutbox}{\hypertarget{t1}{}}{snow}}.\par 

\newpage

\par Wherever Mary went the lamb was \raisebox{\ht\strutbox}{\hypertarget{s2}}{}{\hyperlink{t1}{sure }}to go.

\end{document}

XeTeX 会创建一个文件,其格式是 Donald E. Knuth 发明的 .dvi 格式的扩展版本,然后调用另一个程序 (xdvipdfmx) 将其转换为 pdf。这通常在后台进行,您不会注意到。

pdfTeX 直接创建 .pdf 文件。因此,与 XeTeX 不同,pdfTeX 内置支持跟踪命名目的地=目标=锚点=“命名导航点”是否已多次定义,以及跟踪由 a 表示的“命名导航点”是否\hyperlink不存在。在这种情况下,使用基于 pdfTeX 的引擎会将警告写入 .log 文件和控制台。

与 Knuth 的 TeX 一样,XeTeX 没有内置对跟踪此类事物的支持。它只是创建一个扩展 dvi 格式的输出文件,然后调用转换为 .pdf 的程序。\specials以扩展 .dvi 格式写入文件,其中包含用于创建超链接和超目标的指令,这些指令由转换为 pdf 的程序处理。但是,转换为 pdf 的程序也没有内置支持来跟踪缺失的命名目标。

所以:

  • 如果您使用基于 XeTeX 的 TeX 引擎编译上述示例,则将看不到警告消息,因为与基于 pdfTeX 的 TeX 引擎不同,XeTeX 引擎没有内置支持跟踪丢失或重复的命名目的地 = 目标 = 锚点 =“命名导航点”。

  • 如果你使用基于 pdfTeX 的 TeX 引擎/pdflatex 编译上述示例,你会在控制台和 .log 文件中收到以下警告:

    pdfTeX warning (ext4): destination with the same identifier (name{t1}) has been already used, duplicate ignored
    
    pdfTeX warning (dest): name {s1} has been referenced but does not exist, replaced by a fixed one
    
  • 如果您使用 xelatex 编译示例,并使用 -option -no-pdf,那么您将获得一个扩展 dvi 格式的文件,而不是 .pdf 文件作为输出文件,扩展名为 .xdv 。如果您xdvipdfmx在该 .xdv 文件上运行转换程序,转换程序会发出警告, xdvipdfmx:warning: Object @t1 already defined.这对应于 pdflatex 关于“具有相同标识符的目标”的警告。

(您没有说您使用什么平台/编辑器/IDE。
如果使用 overleaf 的在线平台,您可能需要单击“查看原始日志”才能看到正在使用的 LaTeX 编译器生成的所有消息。)

如果您遇到\hypertargets 和\hyperlinks 问题,通常最好使用基于 pdfTeX 的 TeX 引擎进行编译,这样就可以查看基于 pdfTeX 的引擎提供的警告消息。因为这些消息通常会提示超链接和超目标是否匹配。

pdfTeX 引擎提供的警告告诉我们问题是:

  • 尝试将名为目的地=目标=锚点=名称的“命名导航点”放入 .pdf 文件中的尝试t1不止一次。如果允许这样做,则将名称分配给放入输出文件中的“导航点”将不再是明确的/双射的。
  • 目的地=目标=锚点=名称的“命名导航点”s1未定义/根本没有放入 .pdf 文件中。但尝试创建指向该名称的命名目的地=目标=锚点=“命名导航点”的超链接。

尝试类似以下的操作,其中对于命令实例的参数中出现的每个命名目的地=目标=锚点=“命名导航点”的名称,\hyperlink相应的命名目的地=相应的目标=相应的锚点=相应的“命名导航点”实际上通过以下方式放入 .pdf 文件中\hypertarget

\documentclass[a4paper]{article}

\usepackage{hyperref}

\begin{document}

\par Mary had a little \hyperlink{s1}{\raisebox{\ht\strutbox}{\hypertarget{t1}{}}{lamb}}.\par 

\newpage

% Instead of creating \hypertarget t1 once more the\hypertarget s1 is created.
\par Whose fleece was white as \hyperlink{s2}{\raisebox{\ht\strutbox}{\hypertarget{s1}{}}{snow}}.\par 

\newpage

\par Wherever Mary went the lamb was \raisebox{\ht\strutbox}{\hypertarget{s2}}{}{\hyperlink{t1}{sure }}to go.

\end{document}

无论使用 xelatex 还是 pdflatex,在生成的 .pdf 文件中导航/单击链接都不会导致问题,因为通过\hyperlink命名目的地=目标=锚点=“命名导航点”创建的每个超链接\hypertarget都存在。

\hyperlink但是该示例只是为了显示在提供相应的命名目的地=目标=锚点=“命名导航点”不存在的错误时纠正差异。

如果通过将命名目的地=目标=锚点=“命名导航点”放入 .pdf 文件中\hypertarget,那么您当然可以通过\hyperlink创建多个超链接来“导航”/滚动到命名目的地=目标=锚点=“命名导航点”。

我已经说过,该命令\hypertarget基本上只是触发在 .pdf 文件中创建一个名为目的地=目标=锚点=“命名导航点”。如果您愿意,您可以在第二个参数中提供一些文本,这将导致从该文本创建的第一个事物(框/胶水/内核/任何东西)的参考点和放置在 .pdf 文件中的“命名导航点”相同。

以我的拙见,文本论证\hypertarget只会造成混淆。

与 Ulrike Fischer 一样,我强烈建议不要将\hypertargets 嵌套在\hyperlinks 中,反之亦然,以避免混淆。

而是\hypertarget仅用于放置不带任何文本的“命名导航点”,并确保在单击表示该“命名导航点”的超链接后,该“命名导航点”与您想要在 pdf 查看器显示窗口的左上角看到的框/文本之间没有断点。

最后我可能会做这样的事情:

\documentclass[a4paper]{article}
\usepackage{xcolor}
\usepackage{hyperref}
\hypersetup{%
            %colorlinks=true,
            %linkcolor=blue,
            %filecolor=magenta,
            %urlcolor=cyan,
            %citecolor=green,
            %pdfpagemode=FullScreen
           } 
% ... 
\makeatletter
\NewDocumentCommand\RaisedHypertarget{omo}{%
  % Create a named destination/target/anchor/"named navigation-point" without text.
  % In relation to the baseline of the box which TeX is about to construct 
  % while encountering the command `\RaisedHypertarget`
  % - move named destination/target/anchor/"named navigation-point" up in an amount of #1,
  %   defaults to \baselineskip   
  % - move named destination/target/anchor/"named navigation-point" to the left in an
  %   amount of #3, defaults to 2mm   
  % #1 - Amount of space to move the named destination/target/anchor/"named navigation-point" up
  % #2 - Name of named destination/target/anchor/"named navigation-point"
  % #3 - Amount of space to move the named destination/target/anchor/"named navigation-point" to the left. 
  %      You may need this in case the named destination/target/anchor/"named navigation-point" is at the
  %      left of a hyperlink with borders for ensuring that the "named navigation-point" is not inside the 
  %      link's borders but at the left thereof as well as otherwise things might be scrolled so that you do not see the left
  %      border of that link when navigating to the named destination.
  %
  % For vertical placement use \Hy@raisedlink and probably within a local scope redefine
  %  \HyperRaiseLinkHook and/or \HyperRaiseLinkDefault,
  % see section "8 Help macros for links" of "Hypertext marks in LaTeX", the user manual of hyperref.
  % URL: http://mirrors.ctan.org/macros/latex/contrib/hyperref/doc/hyperref.pdf#section.8
  \begingroup
   \IfNoValueF{#1}{\def\HyperRaiseLinkDefault{#1}}%
   \IfNoValueTF{#3}{\Hy@raisedlink{\hypertarget{#2}{}}}%
                   {\Hy@raisedlink{\kern\dimexpr-#3\relax\hypertarget{#2}{}\kern\dimexpr#3\relax}}%
  \endgroup
}%
\makeatother

\begin{document}%
\pagecolor{white}%
\noindent Mary had a little \hyperlink{s1}{lamb}.
\par
\noindent Whose fleece was white as \hyperlink{s2}{snow}.
\par
\noindent Wherever Mary went the lamb was \hyperlink{t1}{sure} to go.
\par\newpage
\noindent Mary had a little \RaisedHypertarget{t1}[1pt]\hyperlink{s1}{lamb}.
\par\newpage
\noindent Whose fleece was white as \RaisedHypertarget{s1}[1pt]\hyperlink{s2}{snow}.
\par\newpage
\noindent Wherever Mary went the lamb was \RaisedHypertarget{s2}[1pt]\hyperlink{t1}{sure} to go.
\par\newpage
\noindent Mary had a little \hyperlink{s1}{lamb}.
\par
\noindent Whose fleece was white as \hyperlink{s2}{snow}.
\par
\noindent Wherever Mary went the lamb was \hyperlink{t1}{sure} to go.
\end{document}

您可以使用 xelatex 和 pdflatex 编译此示例。pdflatex
不会提供与缺失/重复的命名目的地=目标=锚点="命名导航点" 相关的警告消息。

如您所见,有多个链接指向命名的目的地=目标=锚点="命名导航点"s1和。s2t1

我建议使用非常大的缩放比例来查看生成的 pdf,这样除了垂直滚动之外,您还可以看到单击超链接时内容如何水平滚动。

答案2

非常感谢 Ulrich Diez 对多个超链接指向单一目标的问题的阐释。

我在下面发布了我的糟糕的解决方案,虽然不是特别新颖,但却不容易找到,因为谷歌搜索和查看超链接文档对我没有任何帮助。

在 pdf 中发现多对一链接是很常见的,但我在 latex 中找不到任何明确的方法。一个典型的场景是一篇论文,其中几个关键词链接到索引或参考书目中的常见参考文献。当滚动到参考文献时,可以单击它本身以返回到文本中的原始关键词。

但是,如果有多个关键词链接到参考文献,那么参考文献会链接回哪一个?据我所知,pdf(或 latex)不支持循环浏览超链接列表(如实现后退按钮的浏览器).. 事实上,Word 或 Google docs 等主流文字处理器也不支持。

我认为 pdf 所做的是从目标参考返回到其中一个链接。我们可以将其称为主页链接。它通常是连接到目标参考的链接列表中的最后一个。至少我有一个包含数百个链接的大型论文 Acrobat 文件,这些链接指向数十个参考文献,就是这样做的。

此图说明了 pdf 如何处理交叉链接,下面是我实现的示意图。

在此处输入图片描述

这是一个我用 xelatex 编译的简单演示文件:

\documentclass[a4paper]{article}

\usepackage{xcolor}

\usepackage[colorlinks]{hyperref}

\hypersetup{colorlinks=true, linkcolor=blue, filecolor=magenta, urlcolor=cyan, citecolor=green, pdfpagemode=FullScreen}

\begin{document}

\pagecolor{white}

\par     \hyperlink{s1}{\raisebox{\ht\strutbox}{\hypertarget{t1}{}}{Target link}}. 

\par     \hyperlink{t1}{First link}. 

\par     \hyperlink{t1}{Second link }

\par     \hyperlink{t1}{Third link }

\par     \hyperlink{t1}{\raisebox{\ht\strutbox}{\hypertarget{s1}{}}{Home link }}

\par 
\end{document}

这对我的目的来说已经足够了,但欢迎任何进一步的想法或改进。

相关内容