hyperref 链接与 pdftex + babel + Hebrew (或从右到左的语言) 断开

hyperref 链接与 pdftex + babel + Hebrew (或从右到左的语言) 断开

使用该babel软件包编写希伯来语文本会暴露出与各种其他软件包的不兼容性。此问题与 不兼容性有关hyperref

基本上,您无法获得从右到左文本的链接。这是关于方向而不是非拉丁语言的问题 - 由于某种反转,link-start 命令不知何故被放在了末尾。Guy Rutenberg 的博客中描述了这个问题,这里

\cite这是和的MWE \ref

\documentclass{article}
\usepackage[hebrew,english]{babel}
\usepackage{hyperref}
\begin{document}
\section{A section}
\label{mysection}
LTR English cite \cite{MYSRC}. And now in RTL Hebrew:

\selectlanguage{hebrew}
\cite{MYSRC}
\selectlanguage{english}

Let's refer to the current section:

\selectlanguage{hebrew}
\ref{mysection}

\begin{thebibliography}{MYSRC}
\bibitem[MYSRC01]{MYSRC}
The bibliography entry for MYSRC.
\end{thebibliography}
\end{document}

对于这两者(以及\autoref),您将获得:

! pdfTeX error (ext4): pdf_link_stack empty, \pdfendlink used without \pdfstart
link?.
\AtBegShi@Output ...ipout \box \AtBeginShipoutBox 
                                                  \fi \fi 

笔记

  • Vafa Khaligi 的在下面评论可能有助于从“babel”所做的所有事情中隔离出最少的违规代码,尽管我不能肯定地说。
  • 我链接到的博客条目有一个解决方法 - 仅适用于 xetex。它可以以某种方式适应吗?
  • Stefan Kottwitz 提出了一个解决方法,并因此获得了悬赏。但我真正想要的是让 hyperref 以某种方式正确获取此类链接。

答案1

这不是答案。我能够提供最小的工作示例:

\documentclass{article}
\usepackage{hyperref}
\TeXXeTstate=1
\def\neweverypar{{\setbox0\lastbox\beginR\usebox0}}
\let\origeverypar=\everypar
\def\everypar#1{\origeverypar{\neweverypar#1}}
\begin{document}
This is \href{http://google.com}{Google} and ...
\end{document}

运行此程序后pdflatex,您会收到完全相同的错误消息。我还将此转发给了 Heiko Oberdiek,如果他回答我,我会在此处发布他的答案,但我认为这实际上似乎是带有 TeX--XeT 算法的 pdfTeX 引擎的限制(该算法已经存在许多烦人的错误),而且结果可能是无法修复的。XeTeX 和 PDFTeX 都使用 TeX--XeT,但 PDFTeX 的 hyperref 使用 PDFTeX 原语来表示超文本,而在 XeTeX 中,它使用\special

编辑:以下是 Heiko Oberdiek 的逐字回应:

我不知道。据我所知,甚至没有一种简单的方法来测试 \beginR 或 \beginL 是否有效。一种解决方法是放置两个有一定距离的标签以找出书写方向,这样就可以在必要时切换 \pdfstartlink 和 \pdfendlink 的顺序。但这种解决方法无法扩展,TeX 中的哈希表大小有限,包含许多链接的大型文档很容易达到极限。

在 LuaTeX 中,可以检查节点列表,并且可以在 Lua 级别进行切换。

我还问他,为什么这个问题发生在 PDFTeX 上,而 XeTeX 上不会发生。以下是他的回答:

也许 \specials 会在 xdvipdfmx 中自动重新排序。

答案2

使用 xelatex 的 bidi 包。您或许也可以将 bidi 更改应用于 pdfTeX(xetex 和 pdftex 都使用 etex 进行 bidi 排版,因此应该不会有问题)。我稍微更改了您的示例以使用 polyglossia(因此使用 bidi):

\documentclass{article}
\usepackage{hyperref}
\usepackage{polyglossia}
\setmainlanguage{english}
\setotherlanguage{hebrew}
\newfontfamily\hebrewfont[Script=Hebrew]{Ezra SIL} % from SIL
\begin{document}
\section{A section}
\label{mysection}
LTR English reference \autoref{mysection}. And now in RTL Hebrew:

\begin{hebrew}
הוא פשוט טקסט גולמי של תעשיית ההדפסה וההקלדה. Lorem Ipsum היה טקסט סטנדרטי עוד במאה ה-16, כאשר הדפסה לא ידועה לקחה מגש של דפוס ועירבלה אותו כדי ליצור סוג של ספר דגימה. ספר זה שרד לא רק חמש מאות שנים אלא גם את הקפיצה לתוך ההדפסה
\autoref{mysection}
יש המון גרסאות זמינות לפסקאות של . אבל רובם עברו שינויים בצורה זו או אחרת, על ידי השתלת הומור או מילים אקראיות שלא נראות אפילו מעט אמינות. אם אתה הולך להשתמש במקטעים של של Lorem Ipsum אתה צריך להיות בטוח שאין משהו מביך חבוי בתוך 
\end{hebrew}
\end{document}

结果如下所示:

在此处输入图片描述

答案3

hyperref提供无需创建超链接即可引用的命令,例如\ref*\autoref*

如果我使用,您的示例是可编译的\autoref*

\selectlanguage{hebrew}
\autoref*{mysection}

希伯来语 autoref 示例

您甚至可以关闭文档部分内容的超链接,例如

\makeatletter
\newcommand*{\disablehref}{%
  \let\ref\@refstar
  \DeclareRobustCommand*{\autoref}{\HyRef@autoref\@gobbletwo}}
\makeatother

在群组或环境中使用它,以限制效果,或创建类似的宏\enablehref

这里有一个宏,其工作原理与选项\disablehyperlinks类似,禁用超链接。因此,、和适用于希伯来语。同样,在组或环境中使用它来限制效果。代码和组合示例:drafthyperref\autoref\ref\cite\url

\documentclass{article}
\usepackage[hebrew,english]{babel}
\usepackage{hyperref}
\makeatletter
\newcommand*{\disablehyperlinks}{
  % This is is for compatibility for hyperref versions 6.82d and older
  \@ifundefined{Hy@xspace@end}{
    \let\Hy@xspace@end\relax
  }{}
  \let\hyper@@anchor\@gobble
  \def\hyper@link##1##2##3{##3\Hy@xspace@end}%
  \def\hyper@anchorstart##1##2{##2\Hy@xspace@end}%
  \def\hyper@anchorend{\Hy@xspace@end}%
  \let\hyper@linkstart\@gobbletwo
  \def\hyper@linkend{\Hy@xspace@end}%
  \def\hyper@linkurl##1##2{##1\Hy@xspace@end}%
  \def\hyper@linkfile##1##2##3{##1\Hy@xspace@end}%
  \def\hyper@link@[##1]##2##3##4{##4\Hy@xspace@end}%
}
\makeatother
\begin{document}
\section{A section}
\label{mysection}
LTR English cite \cite{MYSRC} in \autoref{mysection} on \url{tex.stackexchange.com}.
And now in RTL Hebrew:

\begingroup
\disablehyperlinks
\selectlanguage{hebrew}
\cite{MYSRC}

\autoref{mysection}

\url{tex.stackexchange.com}

\endgroup
\selectlanguage{english}
Now again LTR English cite \cite{MYSRC} in \autoref{mysection} on
\url{tex.stackexchange.com}.
\begin{thebibliography}{MYSRC}
\bibitem[MYSRC01]{MYSRC}
The bibliography entry for MYSRC.
\end{thebibliography}
\end{document}

希伯来语,超链接已禁用

答案4

这不是一个实用的解决方案,而是一个概念验证。我没有费心去强化任何命令,也没有按正确的顺序排版引文文本(我想?顺序应该是怎样的?)。

无论如何,这是一个可能的起点:

\documentclass{article}
\usepackage[hebrew,english]{babel}
\usepackage{hyperref}


\let\origcite\cite
\def\cite#1{\beginL\hbox{\origcite{#1}}\endL}
\makeatletter
\def\@cite#1#2{[{#1\if@tempswa , #2\fi }]}
\makeatother
\let\origref\ref
\AtBeginDocument{%
    \def\ref#1{\beginL\hbox{\origref{#1}}\endL}
}

\begin{document}
    \section{A section}\label{mysection}
    
    LTR English cite \cite{MYSRC}. And now in RTL Hebrew:
    
    \selectlanguage{hebrew}
    \cite{MYSRC}
    \selectlanguage{english}
    
    Let's refer to the current section:
    
    \selectlanguage{hebrew}
    \ref{mysection}
    
    \begin{thebibliography}{MYSRC}
        \bibitem[MYSRC01]{MYSRC}
        The bibliography entry for MYSRC.
    \end{thebibliography}
\end{document}

在此处输入图片描述

希望 11 年后你还会觉得它有用...:)

相关内容