再次,引文链接未按分页符拆分

再次,引文链接未按分页符拆分

我偶然发现了一个罕见的臭名昭著的案例\pdfendlink 最终与 \pdfstartlink 处于不同的嵌套级别错误在最新的系统(Ubuntu 14.10,6.83m hyperref)上。如果全部满足以下条件:

  • 双列模式
  • 当链接跨越两个页面时
  • 当链接的起点与同一页面上的图形跨越两列时。

请注意,对于不跨一页但跨两行的链接,natbib 和 hyperref 的(作者,年份)样式产生两个链接(正确)。该问题仅发生在页面边界。此外,该问题不会发生在单列模式下(请参阅修改示例)。这个数字似乎也是必要的(见另一个修改的例子)。

在开发文档期间,解决此问题的最佳方法是什么?(我发现可点击的链接很有用,而且我现在也更喜欢坚持使用双列模式。)从hyperref技术上讲可以修复吗?

这可以看作是其中之一错误报告问题。虽然我知道这一点,但解决方法可能仍然有用有限的修复传播到 Ubuntu LTS 所需的时间(可能长达四年,对某些人来说是永恒)。因此,它可能对文档目的有用;如果不合适,请随时关闭。

MWE(也在 GitHub 上

...对我来说最小但不幸的是并不小,并且使用btxdoc.bib来自natbib

\documentclass[a5paper,twocolumn]{scrartcl}
\pagestyle{empty}
% Fatal combination
\usepackage{natbib,hyperref}

% For constructing the MWE
\usepackage{mwe,lipsum}

\bibliographystyle{chicago}

\begin{document}
  \begin{figure*}[t]
    \includegraphics[width=\textwidth]{example-image-golden}
  \end{figure*}
  \lipsum[1]
  \lipsum[1]
  \lipsum[2]
  Test line break:
  \citep{strunk-and-white}
  Works for first word.
  \citep{strunk-and-white}
  And for second.

  Conclusion: Line breaks work well.

  Now what happens if we force the break at the page boundary?
  Let's take a look

  We make this just long enough to break the link at page boundary
  \citep{strunk-and-white}
  \bibliography{btxdoc}
\end{document}

错误信息

! pdfTeX error (ext4): \pdfendlink ended up in different nesting level than \pd
fstartlink.
\AtBegShi@Output ...ipout \box \AtBeginShipoutBox 
                                                  \fi \fi 
l.33 \end{document}

输出

(第 2 页)稍作修改的非破坏性示例:

输出的第 2 页(根据需要)

答案1

横跨两列的浮动对象 ( ) 是这里的罪魁祸首,因为它在包含打开引用超链接figure*的输出页面中引入了额外的装箱级别。\pdfstartlink

接下来的页面是“正常”的双列页面,没有浮动,因此结尾\pdfendlink处有一个少一级的框。

为了解决这个问题,我们可以为有问题的 增加一个装箱级别\pdfendlink。为此,下面的示例定义了

\addOneNestingLevelEndLink

它被插入到有问题的命令之前\citep

也可能出现相反的情况,即在引用超链接结束的页面上放置两列浮动。此时, \pdfstartlink必须增加命令的装箱级别。因此,

\addOneNestingLevelStartLink ,

同样,要放在相关引用命令的前面。可以一次使用其中一个命令。

示例(分享LaTeX):

\documentclass[a5paper,twocolumn]{scrartcl}

\usepackage{filecontents}
\begin{filecontents}{btxdoc.bib}
@BOOK{strunk-and-white,
   author = "Strunk, Jr., William and E. B. White",
   title = "The Elements of Style",
   publisher = "Macmillan",
   edition = "Third",
   year = 1979 }
\end{filecontents}
\pagestyle{empty}

\usepackage{natbib}
\usepackage[colorlinks,citecolor=blue]{hyperref}

% For constructing the MWE
\usepackage{mwe,lipsum}

\bibliographystyle{chicago}

\makeatletter\ifdefined\Hy@StartlinkName
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \addOneNestingLevelStartLink
% \addOneNestingLevelEndLink
%
% put ONE of \addOneNestingLevel(Start|End)Link in front of offending \cite
% depending on the placement of the double-column float object
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\addOneNestingLevelStartLink{%
  \gdef\Hy@StartlinkName##1##2{%
    \sbox0{\Hy@StartlinkNameOrig{##1}{##2}}\usebox0
    \global\let\Hy@StartlinkName\Hy@StartlinkNameOrig%
  }%
}
\def\addOneNestingLevelEndLink{%
  \gdef\pdfendlink{%
    \sbox0{\pdfendlinkOrig}\usebox0%
    \global\let\pdfendlink\pdfendlinkOrig%
  }%
}
\let\Hy@StartlinkNameOrig\Hy@StartlinkName
\let\pdfendlinkOrig\pdfendlink
\else
\let\addOneNestingLevelStartLink\relax
\let\addOneNestingLevelEndLink\relax
\fi
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatother

\begin{document}
  \begin{figure*}[t]
    \includegraphics[width=\textwidth]{example-image-golden}
  \end{figure*}
  \lipsum[1]
  \lipsum[1]
  \lipsum[2]
  Test line break:
  \citep{strunk-and-white}
  Works for first word.
  \citep{strunk-and-white}
  And for second.

  Conclusion: Line breaks work well.

  Now what happens if we force the break at the page boundary?
  Let's take a look

  We make this just long enough to break the link at page boundary
  \addOneNestingLevelEndLink\citep{strunk-and-white}
  \bibliography{btxdoc}
\end{document}

答案2

在文档开发过程中,解决这个问题的好办法是什么?(我发现可点击的链接很有用,而且我现在更喜欢坚持使用双列模式。)从技术上讲,可以修复 hyperref 吗?

我在这里找到了这个解决方法,至少在文档仍在处理时有效:https://binhngq.blogspot.de/2015/11/pdfendlink-ended-up-in-different.html

只需输入

\hypersetup{draft}

加载 hyperref 包后。这会使您的文档编译,但链接不起作用。这样您就不会在多个中间阶段遇到问题。我的文档遇到了这个问题,无法编译文档的中间阶段真的很烦人。最终版本在没有解决方法的情况下运行良好。如果您的最终版本恰好有这个问题,并且您希望它有链接,那么不幸的是这无济于事。

相关内容