# undefined control sequence when cross-referencing with xr-hyper

I'm trying to create references between two documents. Normally it works great, but I can't figure out why using siunitx inside a chapter name, causes build errors.

Simple example:

doc1.tex

\documentclass{book}
\usepackage{siunitx,xr-hyper,hyperref,lipsum}
\sisetup{detect-all=true}
\externaldocument{doc2}
\begin{document}
\chapter{Test \SI{1}{\GeV}}
\label{chap:test1}
\lipsum[1]
\ref{chap:test2}
\end{document}


doc2.tex

\documentclass{book}
\usepackage{siunitx,xr-hyper,hyperref,lipsum}
\externaldocument{doc1}
\begin{document}
\chapter{Test \SI{2}{\GeV}}
\label{chap:test2}
\lipsum[1]
\ref{chap:test1}
\end{document}


Build sequence

$pdflatex doc1.tex ...(no errors)$ pdflatex doc2.tex
! Undefined control sequence.
<argument> Test \SI {1}{\GeV
}\relax


I've narrowed it down to when externaldocument opens doc1.aux, it errors on the last line:\newlabel{chap:test1}{{1}{1}{Test \SI {1}{\GeV }\relax }{chapter.1}{}} properly.

Is there some way to make it parse the aux file properly?

Package xr-hyper expands the label contents. A better replacement for xr-hyper is zref-xr that also can import and export LaTeX labels:

\documentclass{book}
\usepackage{siunitx,hyperref,lipsum}

\usepackage{nameref,zref-xr}
\zxrsetup{toltxlabel}
\zexternaldocument*{doc1}

\begin{document}
\chapter{Test \SI{2}{\GeV}}
\label{chap:test2}
\lipsum[1]
\ref{chap:test1}, \nameref{chap:test1}
\end{document}


Package nameref should be loaded before \zexternaldocument, because it changes the internal reference format. hyperref loads nameref later in \begin{document}.

• What exactly is it that zref-xr does differently in this regard? Because when using TeX4ht, \Configure{xr} with a custom Link command as per cvr.cc/?p=362 is apparently ignored. The link text is correct, though. – pazathoth Apr 10 '18 at 14:34

 \let\GeV\relax


to each document before the call to \externaldocument

and it should run without error.

nameref's \GetTitleString retrieves the sectional title and stores it in \@currentlabelname. You can override this before making the \label so that it doesn't include the macro contents from siunitx. The macro \updatelabelname{<new name>} below does this:

\makeatletter
\newcommand*{\updatelabelname}[1]{% For correcting \@currentlabelname, if needed
\xdef\@currentlabelname{#1}}
\makeatother


Include the above in both documents and use

### doc1.tex

\chapter{Test \texorpdfstring{\SI{1}{\GeV}}{1 GeV}}
\updatelabelname{Test 1 GeV}


### doc2.tex

\chapter{Test \texorpdfstring{\SI{2}{\GeV}}{2 GeV}}
\updatelabelname{Test 2 GeV}


Also note the use of \texorpdfstring to correctly switch between TeX-related (like ToC) and PDF content (like bookmarks), in general.

• Thanks for the insight on using \texorpdfstring. – h0tw1r3 Oct 17 '12 at 14:51