使用 lineno 和 xr-hyper 对行号进行外部交叉引用

使用 lineno 和 xr-hyper 对行号进行外部交叉引用

source.tex我尝试从文档中引用行号dest.tex。 (PdfLaTeX-) 编译时dest,出现以下错误。

! Extra \else.
\@hyper@readexternallink ...#7\\{#3}{#2}{#7}\else 
                                      \ifx \@pdftempa \@pdftempw...
l.10 ...:mylinelabel}{line \ref*{lin:mylinelabel}}
                                              .

这是source.tex

\documentclass{article}
\usepackage{lineno}
\usepackage{hyperref}
\newcommand{\llabel}[1]{\hypertarget{lintarget:#1}{}\linelabel{lin:#1}}

\begin{document}
\linenumbers

The label is \llabel{mylinelabel} here.

Reference to line: \ref*{lin:mylinelabel}.

Reference with ref as argument: \href{file:source.pdf\#lintarget:mylinelabel}{line \ref*{lin:mylinelabel}}.
\end{document}

这是dest.tex

\documentclass{article}
\usepackage{xr-hyper}
\usepackage{hyperref}
\externaldocument{source}
\newcommand{\lref}[1]{}

\begin{document}
Reference to line in source: \href{file:source.pdf\#lintarget:mylinelabel}{line} \ref*{lin:mylinelabel}.

Reference to line in source with ref as argument: \href{file:source.pdf\#lintarget:mylinelabel}{line \ref*{lin:mylinelabel}}.
\end{document}

中的第二个引用dest.tex触发了错误。唯一的区别是 位于参数ref*内部href。错误似乎源于 、 和 之间的一些微妙交互lineno:在xr-hyper参数中包含命令通常不会引起问题,正如在which 中看到的那样,编译得很好。ref*hrefref*hrefsource.tex

请注意,必须使用ref*而不是ref,否则在编译时dest会出现以下错误。

Runaway argument?
{\@firstoffive }\fi . \end {document} 
! File ended while scanning use of \Hy@setref@link.
<inserted text> 
            \par 
<*> dest.tex

(我受到启发邮政。)

答案1

问题是lineno没有在标签中添加 hyperref 锚点。这会导致xr-hyper假设未使用 hyperref。如果 hyperref\ref命令尝试使用标签,则会导致问题。实际上,这也会\ref*在 的外部触发href:您可以看到行末的句点未打印在 pdf 文件中。

您可以xr-hyper通过添加来解决问题

\makeatletter
  \long\def\myempty{}
  \def\XR@addURL#1{\XR@@dURL#1\myempty{}{}{}{}{}\\}
  \def\XR@@dURL#1#2#3#4#5#6#7\\{%
    {#1}{#2}%
    \ifx\myempty#6\@empty
      {#3}{#4}{\XR@URL}%
    \else
    \fi
  }
\makeatother

在任何\externaldocuments之前dest.tex。这告诉xr-hyper始终添加hyperref样式引用,如果原始引用与 hyperref 兼容。

相关内容