# hyperref links break with babel + hebrew (or right-to-left language)

It's time for Eyal's babel + Hebrew incompatibility of the week. And this time: hyperref... :-(

Basically, you can't get links with right-to-left text. It's about the direction rather than the non-Latin language - somehow the link-start command is placed at the end due to some sort of reversal. The problem is described in Guy Rutenberg's blog, here.

Here's an MWEs for \cite and \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}


For both of these (and for \autoref), you get:

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


Notes:

• Vafa Khaligi's comment below may be useful in isolating the minimum offending code out of everything 'babel' does, although I can't say for sure.
• The blog entry I linked to has a workaround - which only works with xetex. Can it be adapted somehow?
• Stefan Kottwitz suggested a workaround which won a bounty on this question. But what I would really like is to make hyperref get such links correctly somehow.
-
I would suggest to write your question in a group where Heiko Oberdiek is reading (e.g. c.t.t). –  Ulrike Fischer Oct 24 '11 at 10:03
You already got +5 reputation back from me. ;-) –  lockstep Nov 26 '11 at 20:07
@Ulrike: Do you happen to know why Heiko isn't on tex.sx? @ Eyal: The maximum amount of rep any user can offer as a bounty is 500; Stefan and Martin, however, have never offered more than 200. –  doncherry Nov 26 '11 at 23:53
One question, is not it possible that instead running pdflatex on your document, you run xelatex. I am not saying that change your document or use any XeTeX-specific packages but keep your original document (without modifying it) but instead running pdflatex on it, run xelatex on it. –  IRAN Nov 27 '11 at 2:33
@VafaKhalighi: Hmm. Interesting. I just tried running xelatex on my thesis, and it actually compiled (!) only problem was that the Hebrew was replaced with gibberish/empty space, and lots of WARNINGs. Maybe I could make xelatex+babel+Hebrew work somehow, then use the xetex workaround. –  einpoklum Nov 27 '11 at 23:14

This is not an answer. I was able to produce the minimal working example as:

\documentclass{article}
\usepackage{hyperref}
\TeXXeTstate=1
\def\neweverypar{{\setbox0\lastbox\beginR\usebox0}}
\let\origeverypar=\everypar
\def\everypar#1{\origeverypar{\neweverypar#1}}
\begin{document}
\end{document}


after runing pdflatex on this, you get exactly the same error message. I have also forwared this to Heiko Oberdiek and if he answers me, then I post his answer here but I think this actually seems to be a limitation of the pdfTeX engine with TeX--XeT algorithm (the algorithm already have many annoying bugs) and it may turn out that this is not even fixable. XeTeX and PDFTeX both uses TeX--XeT but hyperref with PDFTeX uses PDFTeX primitives for hypertext and in XeTeX, it uses \special.

Edit: This is verbatim response of Heiko Oberdiek:

I don't know. AFAIK there isn't even an easy way to test, whether \beginR or \beginL is active. A workaround could be to put two labels with some distance to find out the writing direction, thus that the order of \pdfstartlink and \pdfendlink could be switched if necessary. But that kind of workaround does not scale, the hash table size in TeX is limited, large document with many links will too easily hit the limit.

In LuaTeX the node lists can be examined and the switches can be done at Lua level.

I also asked him, why this problem happens with PDFTeX and not with XeTeX. Here is his response:

Perhaps the \specials are resorted automatically in xdvipdfmx.

-
I wonder why he says there isn't an easy way... shouldn't \if@rl work? –  einpoklum Nov 27 '11 at 23:00

use bidi package with xelatex. You can perhaps apply bidi changes to pdfTeX too (xetex and pdftex both use etex for bidi typesetting so there should not be a problem). I slightly changed your example to use polyglossia (hence using 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}


and the result is shown below:

-
I can't switch my document, because of all sorts of constraints I can't go into and are more social than technical. I know that there's a workaround when I use bidi+xetex. My question is what can I do with pdftex. Are you saying I can just add the bidi package? I'm kind of assuming it'll create problems either with babel, or with things which conflict/have issues with babel + Hebrew (algorithmicx, other hyperref issues) or with workaround I currently have in place for those things. –  einpoklum Oct 24 '11 at 6:02
No, I did not mean that you can use bidi package with pdfTeX. I meant that you can use bidi changes to hyperref, maybe it works for you. All the changes are in hyperref-xetex-bidi.def . Copy all the macros from this file (obviously except \providesfile lines) and put them between \makeatletter and \makeatother in the preamble of your document. Also bidi uses \if@RTL conditional but babel uses \if@rl. So you also need to change all \if@RTL to \if@rl. –  IRAN Oct 24 '11 at 8:27
I'll just report what I've already wrote Vafa... i TRIED LIFTING macros from hyperref-xetex-bidi.def and adapting them as suggested, but it doesn't work. Maybe it's impossible and maybe it requires more involved modification. –  einpoklum Oct 25 '11 at 6:31
Important to note here that hyperref must be loaded before polyglossia for this solution to work with XeLaTeX. –  fheshwfq Sep 18 '12 at 15:17

hyperref provides commands for referencing without creating hyperlinks, such as \ref* and \autoref*.

Your example is compilable if I use \autoref*:

\selectlanguage{hebrew}
\autoref*{mysection}


You even could switch off hyperlinking for parts of the document, such as by

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


Use it in a group or environment, to limit the effect, or create a similar macro \enablehref.

And here's a macro \disablehyperlinks, which works similar like the draft option of hyperref, disabling hyperlinks. So \autoref, \ref, \cite and \url work with Hebrew. Again, use it in a group or environment to limit the effect. Code and combined example:

\documentclass{article}
\usepackage[hebrew,english]{babel}
\usepackage{hyperref}
\makeatletter
% 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@anchorstart##1##2{##2\Hy@xspace@end}%
\def\hyper@anchorend{\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
\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}


-
What about \cite? (Editing the question to emphasize its importance). I don't think that there's a \cite*, right? –  einpoklum Nov 27 '11 at 7:44
(and of course \url would be replaced with \nolinkurl or something, etc.) –  einpoklum Nov 27 '11 at 8:02
@EyalRozenberg I added a more complete macro for temporarily disabling hyperlinks. –  Stefan Kottwitz Nov 27 '11 at 13:24
I get: ! Undefined control sequence. \hyper@linkurl #1#2->#1\Hy@xspace@end l.30 \url{tex.stackexchange.com} –  einpoklum Nov 27 '11 at 22:32
@EyalRozenberg Perhaps you've got a different hyperref version. Adjust \disablehyperlinks to the code you find in hyperref.sty in \Hy@AtBeginDocument or update hyperref. –  Stefan Kottwitz Nov 27 '11 at 22:41