Jul 23 2012

One last thing about using HyperRef with Hebrew (in LaTeX)

There was another small problem with the hyperref when a section contains Hebrew and English in the same row.

The problem is caused because the \L{} tag tries to change the font as well as the LTR.

A quick workaround will be to use \beginL … \endL instead of \L{}. But as mentioned, it will won’t change the font, meaning it will use the same font for Hebrew and English.

The better workaround will be to change the code mentioned in the previous post to the following(changes highlighted):

\PreloadUnicodePage{5}

\usepackage{hyperref}

\def\contentsline#1#2#3#4{%
  \ifx\\#4\\%
    \csname l@#1\endcsname{#2}{#3}%
  \else
    \ifcase\Hy@linktoc % none
      \csname l@#1\endcsname{#2}{#3}%
    \or % section
      \csname l@#1\endcsname{%
        \beginL\hyper@linkstart{link}{#4}{\R{#2}}\hyper@linkend\endL
      }{#3}%
    \or % page
      \csname l@#1\endcsname{{#2}}{%
        \hyper@linkstart{link}{#4}{#3}\hyper@linkend
      }%
    \else % all
      \csname l@#1\endcsname{%
        \hyper@linkstart{link}{#4}{#2}\hyper@linkend
      }{%
        \hyper@linkstart{link}{#4}{#3}\hyper@linkend
      }%
    \fi
  \fi
}

\def\LDiG#1{\beginL #1 \endL}
 
\def\pdfstringdef#1#2{%
  \let\LOld\L
  \let\L\LDiG
  \begingroup
    \escapechar`\\%
    \edef\0{\string\0}%
    \edef\1{\string\1}%
    \edef\2{\string\2}%
    \edef\3{\string\3}%
    \ifHy@unicode
      \edef\8{\string\8}%
      \edef\9{\string\9}%
      \fontencoding{PU}%
      \HyPsd@UTFviii
      \def\ifpdfstringunicode##1##2{##1}%
    \else
      \fontencoding{PD1}%
      \def\ifpdfstringunicode##1##2{##2}%
    \fi
    \let\utf@viii@undeferr\HyPsd@utf@viii@undeferr
    \enc@update
    \@inmathwarn\pdfstringdef
    \let\@inmathwarn\HyPsd@inmathwarn
    \let\add@accent\HyPsd@add@accent
    \let\{\textbraceright
    \let\}\textbraceleft
    \let\\\textbackslash
    \let\#\textnumbersign
    \let\$\textdollar
    \let\%\textpercent
    \let\&\textampersand
    \let\_\textunderscore
    \let\P\textparagraph
    \let\ldots\textellipsis
    \let\dots\textellipsis
    \def\\{\pdfstringdefWarn\\}%
    \def\newline{\pdfstringdefWarn\newline}%
    \def\TeX{TeX}%
    \def\LaTeX{La\TeX}%
    \def\LaTeXe{%
      \LaTeX2%
      \ifHy@unicode\textepsilon\else e\fi
    }%
    \def\eTeX{%
      \ifHy@unicode\textepsilon\else e\fi
      -\TeX%
    }%
    \def\SliTeX{Sli\TeX}%
    \def\MF{Metafont}%
    \def\MP{Metapost}%
    \let\fontencoding\@gobble
    \let\fontfamily\@gobble
    \let\fontseries\@gobble
    \let\fontshape\@gobble
    \let\fontsize\@gobbletwo
    \let\selectfont\@empty
    \let\usefont\@gobblefour
    \let\emph\@firstofone
    \let\textnormal\@firstofone
    \let\textrm\@firstofone
    \let\textsf\@firstofone
    \let\texttt\@firstofone
    \let\textbf\@firstofone
    \let\textmd\@firstofone
    \let\textit\@firstofone
    \let\textsc\@firstofone
    \let\textsl\@firstofone
    \let\textup\@firstofone
    \let\normalfont\@empty
    \let\rmfamily\@empty
    \let\sffamily\@empty
    \let\ttfamily\@empty
    \let\bfseries\@empty
    \let\mdseries\@empty
    \let\itshape\@empty
    \let\scshape\@empty
    \let\slshape\@empty
    \let\upshape\@empty
    \let\em\@empty
    \let\rm\@empty
    \let\Huge\@empty
    \let\LARGE\@empty
    \let\Large\@empty
    \let\footnotesize\@empty
    \let\huge\@empty
    \let\large\@empty
    \let\normalsize\@empty
    \let\scriptsize\@empty
    \let\small\@empty
    \let\tiny\@empty
    \let\mathversion\@gobble
    \let\phantom\@gobble
    \let\vphantom\@gobble
    \let\hphantom\@gobble
    \def\textcolor##1##{\@secondoftwo}%
    \def\MakeUppercase{\MakeUppercaseUnsupportedInPdfStrings}%
    \def\MakeLowercase{\MakeLowercaseUnsupportedInPdfStrings}%
    \let\textlatin\@firstofone
    \ltx@IfUndefined{language@group}{}{%
      \csname HyPsd@babel@\language@group\endcsname
    }%
    \HyPsd@GreekPatch
    \HyPsd@SpanishPatch
    \HyPsd@RussianPatch
    \HyPsd@BabelPatch
    \let\@safe@activestrue\relax
    \let\@safe@activesfalse\relax
    \let\cyr\relax
    \let\es@roman\@Roman
    \let\glqq\textglqq
    \let\grqq\textgrqq
    \let\glq\textglq
    \let\grq\textgrq
    \let\flqq\textflqq
    \let\frqq\textfrqq
    \let\flq\textflq
    \let\frq\textfrq
    \let\if@mid@expandable\@firstoftwo
    \HyPsd@AMSclassfix
    \let\hspace\HyPsd@hspace
    \let\label\@gobble
    \let\index\@gobble
    \let\glossary\@gobble
    \let\href\HyPsd@href
    \let\@mkboth\@gobbletwo
    \let\ref\HyPsd@ref
    \let\pageref\HyPsd@pageref
    \let\nameref\HyPsd@nameref
    \let\autoref\HyPsd@autoref
    \let\leavevmode\@empty
    \let\mbox\@empty
    \def\halign{\pdfstringdefWarn\halign\@gobble}%
    \let\ignorespaces\HyPsd@ignorespaces
    \let\Hy@SectionAnchorHref\@gobble
    \HyPsd@CJKhook
    \Hy@pdfstringtrue
    \pdfstringdefPreHook
    \HyPsd@LetUnexpandableSpace\space
    \HyPsd@LetUnexpandableSpace\ %
    \HyPsd@LetUnexpandableSpace~%
    \HyPsd@LetUnexpandableSpace\nobreakspace
    \ltx@IfUndefined{@xspace}{%
      \let\xspace\HyPsd@ITALCORR
    }{%
      \let\xspace\HyPsd@XSPACE
    }%
    \let\/\HyPsd@ITALCORR
    \let\bgroup\/%
    \let\egroup\/%
    \let\discretionary\@gobbletwo
    \def\@ifnextchar{\HyPsd@ifnextchar\@ifnextchar}%
    \def\kernel@ifnextchar{\HyPsd@ifnextchar\kernel@ifnextchar}%
    \def\new@ifnextchar{\HyPsd@ifnextchar\new@ifnextchar}%
    \let\@protected@testopt\HyPsd@protected@testopt
    \let\@protected@testopt@xargs\HyPsd@protected@testopt
    \begingroup
      \let\GenericError\@gobblefour
      \let\GenericWarning\@gobbletwo
      \let\GenericInfo\@gobbletwo
      \ifx\nofrenchguillemets\@undefined
      \else
        \nofrenchguillemets
      \fi
      \let\Hy@temp\xdef
      \let\def\HyPsd@DefCommand
      \let\gdef\HyPsd@DefCommand
      \let\edef\HyPsd@DefCommand
      \let\xdef\HyPsd@DefCommand
      \let\futurelet\HyPsd@LetCommand
      \let\let\HyPsd@LetCommand
      \Hy@temp#1{#2}%
    \endgroup
    \ifx#1\@empty
    \else
      \HyPsd@ProtectSpaces#1%
      \let\HyPsd@String\@empty
      \expandafter\HyPsd@RemoveBraces\expandafter{#1|}%
      \global\let#1\HyPsd@String
      \let\HyPsd@SPACEOPTI\relax
      {%
         \let\HyPsd@String\@empty
         \expandafter\HyPsd@CheckCatcodes#1\HyPsd@End
         \global\let#1\HyPsd@String
      }%
      \expandafter\HyPsd@RemoveMask\expandafter
        |\expandafter\@empty#1\HyPsd@End#1%
      \expandafter\HyPsd@Subst\expandafter{\HyPsd@GLYPHERR}{\relax}#1%
      \let\HyPsd@String\@empty
      \expandafter\HyPsd@GlyphProcess#1\relax\@empty
      \global\let#1\HyPsd@String
      \HyPsd@StringSubst{\\}{\textbackslash}#1%
      \ifHy@unicode
        \expandafter\HyPsd@StringSubst\csname 80\040\endcsname
          \HyPsd@SPACEOPTI#1%
        \edef\Hy@temp@A{\HyPsd@SPACEOPTI\HyPsd@SPACEOPTI\80\273}%
        \expandafter\HyPsd@Subst\expandafter{\Hy@temp@A}%
          {\HyPsd@SPACEOPTI\80\273}#1%
      \else
        \HyPsd@StringSubst{\040}\HyPsd@SPACEOPTI#1%
        \expandafter\HyPsd@Subst\expandafter{%
          \expandafter\HyPsd@SPACEOPTI\expandafter\HyPsd@SPACEOPTI
          \string\273}{\HyPsd@SPACEOPTI\273}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\)}{\80\050}#1%
        \HyPsd@Subst){\80\050}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\050\endcsname
          {\HyPsd@empty\80\050}#1%
      \else
        \HyPsd@StringSubst{\)}{\050}#1%
        \HyPsd@Subst){\050}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\050}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\]}{\80\133}#1%
        \HyPsd@Subst]{\80\133}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\133\endcsname
          {\HyPsd@empty\80\133}#1%
      \else
        \HyPsd@StringSubst{\]}{\133}#1%
        \HyPsd@Subst]{\133}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\133}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\[}{\80\135}#1%
        \HyPsd@Subst[{\80\135}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\135\endcsname
          {\HyPsd@empty\80\135}#1%
      \else
        \HyPsd@StringSubst{\[}{\135}#1%
        \HyPsd@Subst[{\135}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\135}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\>}{\80\074}#1%
        \HyPsd@Subst>{\80\074}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\074\endcsname
          {\HyPsd@empty\80\074}#1%
      \else
        \HyPsd@StringSubst{\>}{\074}#1%
        \HyPsd@Subst>{\074}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\074}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\<}{\80\076}#1%
        \HyPsd@Subst<{\80\076}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\076\endcsname
          {\HyPsd@empty\80\076}#1%
      \else
        \HyPsd@StringSubst{\<}{\076}#1%
        \HyPsd@Subst<{\076}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\076}{\HyPsd@empty\string\)}#1%
      \fi
      \expandafter\HyPsd@Subst\expandafter{\/}\HyPsd@empty#1%
      \ltx@IfUndefined{@xspace}{%
      }{%
        \let\HyPsd@xspace\relax
        \expandafter\HyPsd@Subst\expandafter
          {\HyPsd@XSPACE}\HyPsd@xspace#1%
        \let\HyPsd@xspace\HyPsd@doxspace
      }%
      \xdef#1{#1\HyPsd@empty}%
      \HyPsd@Subst{---}\textemdash#1%
      \HyPsd@Subst{--}\textendash#1%
      \HyPsd@Subst{!`}\textexclamdown#1%
      \HyPsd@Subst{?`}\textquestiondown#1%
      \let\HyPsd@empty\@empty
      \ifHy@unicode
        \HyPsd@StringSubst\(\textparenright#1%
        \HyPsd@Subst(\textparenright#1%
      \else
        \HyPsd@StringSubst\({\051}#1%
        \HyPsd@Subst({\051}#1%
        \HyPsd@StringSubst{\051}{\string\(}#1%
      \fi
      \ifHy@unicode
        \edef\HyPsd@SPACEOPTI{\80\040}%
      \else
        \let\HyPsd@SPACEOPTI\HyPsd@spaceopti
      \fi
      \xdef#1{#1\@empty}%
    \fi
  \endgroup
  \begingroup
    \ifHy@unicode
      \HyPsd@ConvertToUnicode#1%
      \ifx\HyPsd@pdfencoding\HyPsd@pdfencoding@auto
        \ltx@IfUndefined{StringEncodingConvertTest}{%
        }{%
          \EdefUnescapeString\HyPsd@temp#1%
          \ifxetex
            \let\HyPsd@UnescapedString\HyPsd@temp
            \StringEncodingConvertTest\HyPsd@temp\HyPsd@temp
                                      {utf16be}{ascii-print}{%
              \EdefEscapeString\HyPsd@temp\HyPsd@temp
              \global\let#1\HyPsd@temp
              \HyPsd@EscapeTeX#1%
              \Hy@unicodefalse
            }{%
              \HyPsd@ToBigChars#1%
            }%
          \else
            \StringEncodingConvertTest\HyPsd@temp\HyPsd@temp
                                      {utf16be}{pdfdoc}{%
              \EdefEscapeString\HyPsd@temp\HyPsd@temp
              \global\let#1\HyPsd@temp
              \HyPsd@EscapeTeX#1%
              \Hy@unicodefalse
            }{}%
          \fi
        }%
      \fi
    \fi
    \HyPsd@XeTeXBigCharsfalse
    \pdfstringdefPostHook#1%
  \endgroup
  \let\L\LOld
}

Now everything suppose to work as expected.

Note: Line 3 is critical! you have to import hyperref manually (Don’t let LyX do it for you, because the order of the commands is critical)


Jul 18 2012

Latex – Fixing the brackets in hyperref bookmarks for RTL languages (such as Hebrew)

In my last post, I’ve shown a way to fix the hyperref package so it would work with RTL languages.

One of the problem float were that the brackets in the pdf bookmarks were inverse. Again, It’s probably caused by the inverse parsing. The solution for that is pretty simple, replace the function that sets the bookmark and add a code to replace between ‘(‘ and ‘)’ (and for the other brackets as well, i.e. “[]{}<>”)

The “problem” was, that the function I had to replace is pretty long, and I was too lazy in order to find a better solution, therefor you will had one big ugly part of code in your solution (until I will have the time to build my own).

So in order to fix the bracket, all you have to do is to add this code to the preamble:

\def\pdfstringdef#1#2{%
  \begingroup
    \escapechar`\\%
    \edef\0{\string\0}%
    \edef\1{\string\1}%
    \edef\2{\string\2}%
    \edef\3{\string\3}%
    \ifHy@unicode
      \edef\8{\string\8}%
      \edef\9{\string\9}%
      \fontencoding{PU}%
      \HyPsd@UTFviii
      \def\ifpdfstringunicode##1##2{##1}%
    \else
      \fontencoding{PD1}%
      \def\ifpdfstringunicode##1##2{##2}%
    \fi
    \let\utf@viii@undeferr\HyPsd@utf@viii@undeferr
    \enc@update
    \@inmathwarn\pdfstringdef
    \let\@inmathwarn\HyPsd@inmathwarn
    \let\add@accent\HyPsd@add@accent
    \let\{\textbraceright
    \let\}\textbraceleft
    \let\\\textbackslash
    \let\#\textnumbersign
    \let\$\textdollar
    \let\%\textpercent
    \let\&\textampersand
    \let\_\textunderscore
    \let\P\textparagraph
    \let\ldots\textellipsis
    \let\dots\textellipsis
    \def\\{\pdfstringdefWarn\\}%
    \def\newline{\pdfstringdefWarn\newline}%
    \def\TeX{TeX}%
    \def\LaTeX{La\TeX}%
    \def\LaTeXe{%
      \LaTeX2%
      \ifHy@unicode\textepsilon\else e\fi
    }%
    \def\eTeX{%
      \ifHy@unicode\textepsilon\else e\fi
      -\TeX%
    }%
    \def\SliTeX{Sli\TeX}%
    \def\MF{Metafont}%
    \def\MP{Metapost}%
    \let\fontencoding\@gobble
    \let\fontfamily\@gobble
    \let\fontseries\@gobble
    \let\fontshape\@gobble
    \let\fontsize\@gobbletwo
    \let\selectfont\@empty
    \let\usefont\@gobblefour
    \let\emph\@firstofone
    \let\textnormal\@firstofone
    \let\textrm\@firstofone
    \let\textsf\@firstofone
    \let\texttt\@firstofone
    \let\textbf\@firstofone
    \let\textmd\@firstofone
    \let\textit\@firstofone
    \let\textsc\@firstofone
    \let\textsl\@firstofone
    \let\textup\@firstofone
    \let\normalfont\@empty
    \let\rmfamily\@empty
    \let\sffamily\@empty
    \let\ttfamily\@empty
    \let\bfseries\@empty
    \let\mdseries\@empty
    \let\itshape\@empty
    \let\scshape\@empty
    \let\slshape\@empty
    \let\upshape\@empty
    \let\em\@empty
    \let\rm\@empty
    \let\Huge\@empty
    \let\LARGE\@empty
    \let\Large\@empty
    \let\footnotesize\@empty
    \let\huge\@empty
    \let\large\@empty
    \let\normalsize\@empty
    \let\scriptsize\@empty
    \let\small\@empty
    \let\tiny\@empty
    \let\mathversion\@gobble
    \let\phantom\@gobble
    \let\vphantom\@gobble
    \let\hphantom\@gobble
    \def\textcolor##1##{\@secondoftwo}%
    \def\MakeUppercase{\MakeUppercaseUnsupportedInPdfStrings}%
    \def\MakeLowercase{\MakeLowercaseUnsupportedInPdfStrings}%
    \let\textlatin\@firstofone
    \ltx@IfUndefined{language@group}{}{%
      \csname HyPsd@babel@\language@group\endcsname
    }%
    \HyPsd@GreekPatch
    \HyPsd@SpanishPatch
    \HyPsd@RussianPatch
    \HyPsd@BabelPatch
    \let\@safe@activestrue\relax
    \let\@safe@activesfalse\relax
    \let\cyr\relax
    \let\es@roman\@Roman
    \let\glqq\textglqq
    \let\grqq\textgrqq
    \let\glq\textglq
    \let\grq\textgrq
    \let\flqq\textflqq
    \let\frqq\textfrqq
    \let\flq\textflq
    \let\frq\textfrq
    \let\if@mid@expandable\@firstoftwo
    \HyPsd@AMSclassfix
    \let\hspace\HyPsd@hspace
    \let\label\@gobble
    \let\index\@gobble
    \let\glossary\@gobble
    \let\href\HyPsd@href
    \let\@mkboth\@gobbletwo
    \let\ref\HyPsd@ref
    \let\pageref\HyPsd@pageref
    \let\nameref\HyPsd@nameref
    \let\autoref\HyPsd@autoref
    \let\leavevmode\@empty
    \let\mbox\@empty
    \def\halign{\pdfstringdefWarn\halign\@gobble}%
    \let\ignorespaces\HyPsd@ignorespaces
    \let\Hy@SectionAnchorHref\@gobble
    \HyPsd@CJKhook
    \Hy@pdfstringtrue
    \pdfstringdefPreHook
    \HyPsd@LetUnexpandableSpace\space
    \HyPsd@LetUnexpandableSpace\ %
    \HyPsd@LetUnexpandableSpace~%
    \HyPsd@LetUnexpandableSpace\nobreakspace
    \ltx@IfUndefined{@xspace}{%
      \let\xspace\HyPsd@ITALCORR
    }{%
      \let\xspace\HyPsd@XSPACE
    }%
    \let\/\HyPsd@ITALCORR
    \let\bgroup\/%
    \let\egroup\/%
    \let\discretionary\@gobbletwo
    \def\@ifnextchar{\HyPsd@ifnextchar\@ifnextchar}%
    \def\kernel@ifnextchar{\HyPsd@ifnextchar\kernel@ifnextchar}%
    \def\new@ifnextchar{\HyPsd@ifnextchar\new@ifnextchar}%
    \let\@protected@testopt\HyPsd@protected@testopt
    \let\@protected@testopt@xargs\HyPsd@protected@testopt
    \begingroup
      \let\GenericError\@gobblefour
      \let\GenericWarning\@gobbletwo
      \let\GenericInfo\@gobbletwo
      \ifx\nofrenchguillemets\@undefined
      \else
        \nofrenchguillemets
      \fi
      \let\Hy@temp\xdef
      \let\def\HyPsd@DefCommand
      \let\gdef\HyPsd@DefCommand
      \let\edef\HyPsd@DefCommand
      \let\xdef\HyPsd@DefCommand
      \let\futurelet\HyPsd@LetCommand
      \let\let\HyPsd@LetCommand
      \Hy@temp#1{#2}%
    \endgroup
    \ifx#1\@empty
    \else
      \HyPsd@ProtectSpaces#1%
      \let\HyPsd@String\@empty
      \expandafter\HyPsd@RemoveBraces\expandafter{#1|}%
      \global\let#1\HyPsd@String
      \let\HyPsd@SPACEOPTI\relax
      {%
         \let\HyPsd@String\@empty
         \expandafter\HyPsd@CheckCatcodes#1\HyPsd@End
         \global\let#1\HyPsd@String
      }%
      \expandafter\HyPsd@RemoveMask\expandafter
        |\expandafter\@empty#1\HyPsd@End#1%
      \expandafter\HyPsd@Subst\expandafter{\HyPsd@GLYPHERR}{\relax}#1%
      \let\HyPsd@String\@empty
      \expandafter\HyPsd@GlyphProcess#1\relax\@empty
      \global\let#1\HyPsd@String
      \HyPsd@StringSubst{\\}{\textbackslash}#1%
      \ifHy@unicode
        \expandafter\HyPsd@StringSubst\csname 80\040\endcsname
          \HyPsd@SPACEOPTI#1%
        \edef\Hy@temp@A{\HyPsd@SPACEOPTI\HyPsd@SPACEOPTI\80\273}%
        \expandafter\HyPsd@Subst\expandafter{\Hy@temp@A}%
          {\HyPsd@SPACEOPTI\80\273}#1%
      \else
        \HyPsd@StringSubst{\040}\HyPsd@SPACEOPTI#1%
        \expandafter\HyPsd@Subst\expandafter{%
          \expandafter\HyPsd@SPACEOPTI\expandafter\HyPsd@SPACEOPTI
          \string\273}{\HyPsd@SPACEOPTI\273}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\)}{\80\050}#1%
        \HyPsd@Subst){\80\050}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\050\endcsname
          {\HyPsd@empty\80\050}#1%
      \else
        \HyPsd@StringSubst{\)}{\050}#1%
        \HyPsd@Subst){\050}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\050}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\]}{\80\133}#1%
        \HyPsd@Subst]{\80\133}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\133\endcsname
          {\HyPsd@empty\80\133}#1%
      \else
        \HyPsd@StringSubst{\]}{\133}#1%
        \HyPsd@Subst]{\133}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\133}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\[}{\80\135}#1%
        \HyPsd@Subst[{\80\135}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\135\endcsname
          {\HyPsd@empty\80\135}#1%
      \else
        \HyPsd@StringSubst{\[}{\135}#1%
        \HyPsd@Subst[{\135}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\135}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\>}{\80\074}#1%
        \HyPsd@Subst>{\80\074}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\074\endcsname
          {\HyPsd@empty\80\074}#1%
      \else
        \HyPsd@StringSubst{\>}{\074}#1%
        \HyPsd@Subst>{\074}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\074}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\<}{\80\076}#1%
        \HyPsd@Subst<{\80\076}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\076\endcsname
          {\HyPsd@empty\80\076}#1%
      \else
        \HyPsd@StringSubst{\<}{\076}#1%
        \HyPsd@Subst<{\076}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\076}{\HyPsd@empty\string\)}#1%
      \fi
      \expandafter\HyPsd@Subst\expandafter{\/}\HyPsd@empty#1%
      \ltx@IfUndefined{@xspace}{%
      }{%
        \let\HyPsd@xspace\relax
        \expandafter\HyPsd@Subst\expandafter
          {\HyPsd@XSPACE}\HyPsd@xspace#1%
        \let\HyPsd@xspace\HyPsd@doxspace
      }%
      \xdef#1{#1\HyPsd@empty}%
      \HyPsd@Subst{---}\textemdash#1%
      \HyPsd@Subst{--}\textendash#1%
      \HyPsd@Subst{!`}\textexclamdown#1%
      \HyPsd@Subst{?`}\textquestiondown#1%
      \let\HyPsd@empty\@empty
      \ifHy@unicode
        \HyPsd@StringSubst\(\textparenright#1%
        \HyPsd@Subst(\textparenright#1%
      \else
        \HyPsd@StringSubst\({\051}#1%
        \HyPsd@Subst({\051}#1%
        \HyPsd@StringSubst{\051}{\string\(}#1%
      \fi
      \ifHy@unicode
        \edef\HyPsd@SPACEOPTI{\80\040}%
      \else
        \let\HyPsd@SPACEOPTI\HyPsd@spaceopti
      \fi
      \xdef#1{#1\@empty}%
    \fi
  \endgroup
  \begingroup
    \ifHy@unicode
      \HyPsd@ConvertToUnicode#1%
      \ifx\HyPsd@pdfencoding\HyPsd@pdfencoding@auto
        \ltx@IfUndefined{StringEncodingConvertTest}{%
        }{%
          \EdefUnescapeString\HyPsd@temp#1%
          \ifxetex
            \let\HyPsd@UnescapedString\HyPsd@temp
            \StringEncodingConvertTest\HyPsd@temp\HyPsd@temp
                                      {utf16be}{ascii-print}{%
              \EdefEscapeString\HyPsd@temp\HyPsd@temp
              \global\let#1\HyPsd@temp
              \HyPsd@EscapeTeX#1%
              \Hy@unicodefalse
            }{%
              \HyPsd@ToBigChars#1%
            }%
          \else
            \StringEncodingConvertTest\HyPsd@temp\HyPsd@temp
                                      {utf16be}{pdfdoc}{%
              \EdefEscapeString\HyPsd@temp\HyPsd@temp
              \global\let#1\HyPsd@temp
              \HyPsd@EscapeTeX#1%
              \Hy@unicodefalse
            }{}%
          \fi
        }%
      \fi
    \fi
    \HyPsd@XeTeXBigCharsfalse
    \pdfstringdefPostHook#1%
  \endgroup
}

And with the RTL fix from last post, your preamble should look something like the following:

\PreloadUnicodePage{5}

\usepackage[unicode=true] {hyperref}

\def\contentsline#1#2#3#4{%
  \ifx\\#4\\%
    \csname l@#1\endcsname{#2}{#3}%
  \else
    \ifcase\Hy@linktoc % none
      \csname l@#1\endcsname{#2}{#3}%
    \or % section
      \csname l@#1\endcsname{%
        \beginL\hyper@linkstart{link}{#4}{\R{#2}}\hyper@linkend\endL
      }{#3}%
    \or % page
      \csname l@#1\endcsname{{#2}}{%
        \hyper@linkstart{link}{#4}{#3}\hyper@linkend
      }%
    \else % all
      \csname l@#1\endcsname{%
        \hyper@linkstart{link}{#4}{#2}\hyper@linkend
      }{%
        \hyper@linkstart{link}{#4}{#3}\hyper@linkend
      }%
    \fi
  \fi
}

\def\pdfstringdef#1#2{%
  \begingroup
    \escapechar`\\%
    \edef\0{\string\0}%
    \edef\1{\string\1}%
    \edef\2{\string\2}%
    \edef\3{\string\3}%
    \ifHy@unicode
      \edef\8{\string\8}%
      \edef\9{\string\9}%
      \fontencoding{PU}%
      \HyPsd@UTFviii
      \def\ifpdfstringunicode##1##2{##1}%
    \else
      \fontencoding{PD1}%
      \def\ifpdfstringunicode##1##2{##2}%
    \fi
    \let\utf@viii@undeferr\HyPsd@utf@viii@undeferr
    \enc@update
    \@inmathwarn\pdfstringdef
    \let\@inmathwarn\HyPsd@inmathwarn
    \let\add@accent\HyPsd@add@accent
    \let\{\textbraceright
    \let\}\textbraceleft
    \let\\\textbackslash
    \let\#\textnumbersign
    \let\$\textdollar
    \let\%\textpercent
    \let\&\textampersand
    \let\_\textunderscore
    \let\P\textparagraph
    \let\ldots\textellipsis
    \let\dots\textellipsis
    \def\\{\pdfstringdefWarn\\}%
    \def\newline{\pdfstringdefWarn\newline}%
    \def\TeX{TeX}%
    \def\LaTeX{La\TeX}%
    \def\LaTeXe{%
      \LaTeX2%
      \ifHy@unicode\textepsilon\else e\fi
    }%
    \def\eTeX{%
      \ifHy@unicode\textepsilon\else e\fi
      -\TeX%
    }%
    \def\SliTeX{Sli\TeX}%
    \def\MF{Metafont}%
    \def\MP{Metapost}%
    \let\fontencoding\@gobble
    \let\fontfamily\@gobble
    \let\fontseries\@gobble
    \let\fontshape\@gobble
    \let\fontsize\@gobbletwo
    \let\selectfont\@empty
    \let\usefont\@gobblefour
    \let\emph\@firstofone
    \let\textnormal\@firstofone
    \let\textrm\@firstofone
    \let\textsf\@firstofone
    \let\texttt\@firstofone
    \let\textbf\@firstofone
    \let\textmd\@firstofone
    \let\textit\@firstofone
    \let\textsc\@firstofone
    \let\textsl\@firstofone
    \let\textup\@firstofone
    \let\normalfont\@empty
    \let\rmfamily\@empty
    \let\sffamily\@empty
    \let\ttfamily\@empty
    \let\bfseries\@empty
    \let\mdseries\@empty
    \let\itshape\@empty
    \let\scshape\@empty
    \let\slshape\@empty
    \let\upshape\@empty
    \let\em\@empty
    \let\rm\@empty
    \let\Huge\@empty
    \let\LARGE\@empty
    \let\Large\@empty
    \let\footnotesize\@empty
    \let\huge\@empty
    \let\large\@empty
    \let\normalsize\@empty
    \let\scriptsize\@empty
    \let\small\@empty
    \let\tiny\@empty
    \let\mathversion\@gobble
    \let\phantom\@gobble
    \let\vphantom\@gobble
    \let\hphantom\@gobble
    \def\textcolor##1##{\@secondoftwo}%
    \def\MakeUppercase{\MakeUppercaseUnsupportedInPdfStrings}%
    \def\MakeLowercase{\MakeLowercaseUnsupportedInPdfStrings}%
    \let\textlatin\@firstofone
    \ltx@IfUndefined{language@group}{}{%
      \csname HyPsd@babel@\language@group\endcsname
    }%
    \HyPsd@GreekPatch
    \HyPsd@SpanishPatch
    \HyPsd@RussianPatch
    \HyPsd@BabelPatch
    \let\@safe@activestrue\relax
    \let\@safe@activesfalse\relax
    \let\cyr\relax
    \let\es@roman\@Roman
    \let\glqq\textglqq
    \let\grqq\textgrqq
    \let\glq\textglq
    \let\grq\textgrq
    \let\flqq\textflqq
    \let\frqq\textfrqq
    \let\flq\textflq
    \let\frq\textfrq
    \let\if@mid@expandable\@firstoftwo
    \HyPsd@AMSclassfix
    \let\hspace\HyPsd@hspace
    \let\label\@gobble
    \let\index\@gobble
    \let\glossary\@gobble
    \let\href\HyPsd@href
    \let\@mkboth\@gobbletwo
    \let\ref\HyPsd@ref
    \let\pageref\HyPsd@pageref
    \let\nameref\HyPsd@nameref
    \let\autoref\HyPsd@autoref
    \let\leavevmode\@empty
    \let\mbox\@empty
    \def\halign{\pdfstringdefWarn\halign\@gobble}%
    \let\ignorespaces\HyPsd@ignorespaces
    \let\Hy@SectionAnchorHref\@gobble
    \HyPsd@CJKhook
    \Hy@pdfstringtrue
    \pdfstringdefPreHook
    \HyPsd@LetUnexpandableSpace\space
    \HyPsd@LetUnexpandableSpace\ %
    \HyPsd@LetUnexpandableSpace~%
    \HyPsd@LetUnexpandableSpace\nobreakspace
    \ltx@IfUndefined{@xspace}{%
      \let\xspace\HyPsd@ITALCORR
    }{%
      \let\xspace\HyPsd@XSPACE
    }%
    \let\/\HyPsd@ITALCORR
    \let\bgroup\/%
    \let\egroup\/%
    \let\discretionary\@gobbletwo
    \def\@ifnextchar{\HyPsd@ifnextchar\@ifnextchar}%
    \def\kernel@ifnextchar{\HyPsd@ifnextchar\kernel@ifnextchar}%
    \def\new@ifnextchar{\HyPsd@ifnextchar\new@ifnextchar}%
    \let\@protected@testopt\HyPsd@protected@testopt
    \let\@protected@testopt@xargs\HyPsd@protected@testopt
    \begingroup
      \let\GenericError\@gobblefour
      \let\GenericWarning\@gobbletwo
      \let\GenericInfo\@gobbletwo
      \ifx\nofrenchguillemets\@undefined
      \else
        \nofrenchguillemets
      \fi
      \let\Hy@temp\xdef
      \let\def\HyPsd@DefCommand
      \let\gdef\HyPsd@DefCommand
      \let\edef\HyPsd@DefCommand
      \let\xdef\HyPsd@DefCommand
      \let\futurelet\HyPsd@LetCommand
      \let\let\HyPsd@LetCommand
      \Hy@temp#1{#2}%
    \endgroup
    \ifx#1\@empty
    \else
      \HyPsd@ProtectSpaces#1%
      \let\HyPsd@String\@empty
      \expandafter\HyPsd@RemoveBraces\expandafter{#1|}%
      \global\let#1\HyPsd@String
      \let\HyPsd@SPACEOPTI\relax
      {%
         \let\HyPsd@String\@empty
         \expandafter\HyPsd@CheckCatcodes#1\HyPsd@End
         \global\let#1\HyPsd@String
      }%
      \expandafter\HyPsd@RemoveMask\expandafter
        |\expandafter\@empty#1\HyPsd@End#1%
      \expandafter\HyPsd@Subst\expandafter{\HyPsd@GLYPHERR}{\relax}#1%
      \let\HyPsd@String\@empty
      \expandafter\HyPsd@GlyphProcess#1\relax\@empty
      \global\let#1\HyPsd@String
      \HyPsd@StringSubst{\\}{\textbackslash}#1%
      \ifHy@unicode
        \expandafter\HyPsd@StringSubst\csname 80\040\endcsname
          \HyPsd@SPACEOPTI#1%
        \edef\Hy@temp@A{\HyPsd@SPACEOPTI\HyPsd@SPACEOPTI\80\273}%
        \expandafter\HyPsd@Subst\expandafter{\Hy@temp@A}%
          {\HyPsd@SPACEOPTI\80\273}#1%
      \else
        \HyPsd@StringSubst{\040}\HyPsd@SPACEOPTI#1%
        \expandafter\HyPsd@Subst\expandafter{%
          \expandafter\HyPsd@SPACEOPTI\expandafter\HyPsd@SPACEOPTI
          \string\273}{\HyPsd@SPACEOPTI\273}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\)}{\80\050}#1%
        \HyPsd@Subst){\80\050}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\050\endcsname
          {\HyPsd@empty\80\050}#1%
      \else
        \HyPsd@StringSubst{\)}{\050}#1%
        \HyPsd@Subst){\050}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\050}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\]}{\80\133}#1%
        \HyPsd@Subst]{\80\133}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\133\endcsname
          {\HyPsd@empty\80\133}#1%
      \else
        \HyPsd@StringSubst{\]}{\133}#1%
        \HyPsd@Subst]{\133}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\133}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\[}{\80\135}#1%
        \HyPsd@Subst[{\80\135}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\135\endcsname
          {\HyPsd@empty\80\135}#1%
      \else
        \HyPsd@StringSubst{\[}{\135}#1%
        \HyPsd@Subst[{\135}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\135}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\>}{\80\074}#1%
        \HyPsd@Subst>{\80\074}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\074\endcsname
          {\HyPsd@empty\80\074}#1%
      \else
        \HyPsd@StringSubst{\>}{\074}#1%
        \HyPsd@Subst>{\074}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\074}{\HyPsd@empty\string\)}#1%
      \fi
      \ifHy@unicode
        \HyPsd@StringSubst{\<}{\80\076}#1%
        \HyPsd@Subst<{\80\076}#1%
        \let\HyPsd@empty\relax
        \expandafter\HyPsd@StringSubst\csname 80\076\endcsname
          {\HyPsd@empty\80\076}#1%
      \else
        \HyPsd@StringSubst{\<}{\076}#1%
        \HyPsd@Subst<{\076}#1%
        \let\HyPsd@empty\relax
        \HyPsd@StringSubst{\076}{\HyPsd@empty\string\)}#1%
      \fi
      \expandafter\HyPsd@Subst\expandafter{\/}\HyPsd@empty#1%
      \ltx@IfUndefined{@xspace}{%
      }{%
        \let\HyPsd@xspace\relax
        \expandafter\HyPsd@Subst\expandafter
          {\HyPsd@XSPACE}\HyPsd@xspace#1%
        \let\HyPsd@xspace\HyPsd@doxspace
      }%
      \xdef#1{#1\HyPsd@empty}%
      \HyPsd@Subst{---}\textemdash#1%
      \HyPsd@Subst{--}\textendash#1%
      \HyPsd@Subst{!`}\textexclamdown#1%
      \HyPsd@Subst{?`}\textquestiondown#1%
      \let\HyPsd@empty\@empty
      \ifHy@unicode
        \HyPsd@StringSubst\(\textparenright#1%
        \HyPsd@Subst(\textparenright#1%
      \else
        \HyPsd@StringSubst\({\051}#1%
        \HyPsd@Subst({\051}#1%
        \HyPsd@StringSubst{\051}{\string\(}#1%
      \fi
      \ifHy@unicode
        \edef\HyPsd@SPACEOPTI{\80\040}%
      \else
        \let\HyPsd@SPACEOPTI\HyPsd@spaceopti
      \fi
      \xdef#1{#1\@empty}%
    \fi
  \endgroup
  \begingroup
    \ifHy@unicode
      \HyPsd@ConvertToUnicode#1%
      \ifx\HyPsd@pdfencoding\HyPsd@pdfencoding@auto
        \ltx@IfUndefined{StringEncodingConvertTest}{%
        }{%
          \EdefUnescapeString\HyPsd@temp#1%
          \ifxetex
            \let\HyPsd@UnescapedString\HyPsd@temp
            \StringEncodingConvertTest\HyPsd@temp\HyPsd@temp
                                      {utf16be}{ascii-print}{%
              \EdefEscapeString\HyPsd@temp\HyPsd@temp
              \global\let#1\HyPsd@temp
              \HyPsd@EscapeTeX#1%
              \Hy@unicodefalse
            }{%
              \HyPsd@ToBigChars#1%
            }%
          \else
            \StringEncodingConvertTest\HyPsd@temp\HyPsd@temp
                                      {utf16be}{pdfdoc}{%
              \EdefEscapeString\HyPsd@temp\HyPsd@temp
              \global\let#1\HyPsd@temp
              \HyPsd@EscapeTeX#1%
              \Hy@unicodefalse
            }{}%
          \fi
        }%
      \fi
    \fi
    \HyPsd@XeTeXBigCharsfalse
    \pdfstringdefPostHook#1%
  \endgroup
}

Jul 16 2012

LaTeX – Using hyperref with RTL languages (such as Hebrew)

Long ago I’ve tried to use hyperref(which allowing links inside the documents, and bookmarks in pdf output) package in latex while writing in Hebrew. Sadly I’ve failed and didn’t have time to check why.

Today, After encountering this post by a guy asking for help in this situation I’ve managed to work around most of the problems.

At first I’ve found Guy Rutenberg’s post about “Getting Hyperref to Work with Hebrew (in XeTeX)“.
Which made me understand why pdfLaTeX failed miserably.
Guy used XeTeX, which might be fine for you, but I’m using a lot of packages and some of them just doesn’t support XeTeX. So, I thought, maybe ps2pdf will work?

Now it is a good time to say, I’m using LyX. I’m not writing the latex code directly, so that’s why my next choice was ps2pdf, because it’s one of LyX defaults.

I’ve tried to compile a simple article with a table of contents and sections. I had a small smile on my face when it managed to compile, but when I’ve opened the PDF it was one big mass. All the bookmarks were blank. After playing around with it, I figured out that the problem was the encoding of the document. For some reason LyX doesn’t like Unicode so it doesn’t use it by default and ps2pdf doesn’t like other Hebrew encoding at all.

So, first of all, you will have to change the encoding. In LyX You can do that by:

  1. clicking Documet > Settings…
  2. Go to the Language tab.
  3. In the Encoding section choose Other and then Unicode (ucs-extended) (utf8x).

If you are writing a latex code, just write:

\usepackage[utf8x]{inputenc}

In the preamble (and remove the other inputenc importing if exists).

Now when I’ve compiled the document the bookmark were OK, but the links in the table of content weren’t in the right place. The problem as it seems to be, was the very same problem Guy mentioned, parts of document are being processed in a reversed order because of the RTL. The solution for that, was to find the specific buildup of the TOC and change the RTL to LTR before setting up the link and then back for the text itself. So, when I’ve added the following to the preamble everything worked just fine:

\PreloadUnicodePage{5}

\usepackage[unicode=true] {hyperref}

\def\contentsline#1#2#3#4{%
  \ifx\\#4\\%
    \csname l@#1\endcsname{#2}{#3}%
  \else
    \ifcase\Hy@linktoc % none
      \csname l@#1\endcsname{#2}{#3}%
    \or % section
      \csname l@#1\endcsname{%
        \beginL\hyper@linkstart{link}{#4}{\R{#2}}\hyper@linkend\endL
      }{#3}%
    \or % page
      \csname l@#1\endcsname{{#2}}{%
        \hyper@linkstart{link}{#4}{#3}\hyper@linkend
      }%
    \else % all
      \csname l@#1\endcsname{%
        \hyper@linkstart{link}{#4}{#2}\hyper@linkend
      }{%
        \hyper@linkstart{link}{#4}{#3}\hyper@linkend
      }%
    \fi
  \fi
}

By adding it, you are replacing the hyperref‘s contentsline function. The only difference between the original function and the new one is at line 13. the \beginR, \endR and \L{…}.

I’m not really sure if it’s 100% bulletproof, so let me know if you encounter any problems.