使用带有 xr pakcage 的 Sublime Text 3 在 latextools 中自动填充多个文件中的标签

使用带有 xr pakcage 的 Sublime Text 3 在 latextools 中自动填充多个文件中的标签

我有三个 tex 文件:文件 1. 主论文;文件 2. 补充文件;文件 3. 审稿报告。如您所见,没有“主”文件。但是,我希望能够在一个文件中引用另一个文件中的标签。我使用 xr 包来执行此操作。但是,Latextools(在 Sublime Text 3 中)似乎无法识别这一点,并且不会将其他文件中的标签作为自动完成列表中的选项提供。

文件1如下:

\documentclass[aos,preprint]{imsart}
\usepackage{xr}
\externaldocument{File2.tex}
\begin{document}
I want Latetools to autofill this reference: \ref{eq:Heat}
\begin{equation}\label{eq:test}
  a^m+ b^m= c^m
\end{equation}
\end{document}

文件2如下:

\documentclass[aos,preprint]{imsart}
\usepackage{xr}
\externaldocument{File1.tex}
\begin{document}
I want Latetools to autofill this reference: \ref{eq:test}
\begin{equation}\label{eq:Heat}
  \frac{\partial u}{\partial t} -\alpha \nabla^2 u =0
\end{equation}
\end{document}

我尝试查看“latex_ref_completions.py”,但是其中说 Latextools“递归搜索所有链接的 tex 文件以找到全部”,但我不确定如何“链接”这两个文件。

答案1

我会留下答案,因为有一个类似问题就在三天前。

这里的问题是经典的“只有 TeX 才能解析 TeX”。但这到底意味着什么呢?大多数实际的编程语言都有某种固定的语法。例如,在 C 语言中(虽然我不太了解 C 语言,但是……)for无论如何,语句总是具有相同的语法并执行相同的操作,因为这就是 C 的工作方式。代码:

#include <stdio.h>
int main()
{
    int n;
    for(n = 1; n <= 10; ++n)
    {
        printf("%d, ", n);
    }
    printf("\n");
    return 0;
}

总是会在任何地方打印1, 2, 3, 4, 5, 6, 7, 8, 9, 10,。用纯 TeX 编写的程序可以执行相同的操作:

\newcount\n
\n=0
\loop
  \ifnum\n<10
  \advance\n by 1
  \the\n,
\repeat
\bye

因为\loop定义为:

\def\loop#1\repeat{\def\body{#1}\iterate}
\def\iterate{\body \let\next\iterate \else\let\next\relax\fi \next}
\let\repeat=\fi

问题是,在 C 语言中,任何词法分析器都知道如何进行正确的语法高亮(如果代码不是混淆,当然),原则上它是正确的。在 TeX 中,如果某个语法高亮程序很聪明,知道 的作用\loop...\repeat,你就可以很容易地欺骗它:

\def\loop#1\nope{\def\body{#1}\iterate}
\let\nope=\fi

然后只需使用\loop...\nope,词法分析器就会迷失方向。这(某种程度上)解释了为什么“只有 TeX 可以解析 TeX”。TeX 会知道 的含义\loop已经改变并会相应地使用它,但词法分析器必须解析它\def并更新 的定义才能\loop做出正确的选择。

但是让我们乐观一点,假设我们的非 TeX TeX 解析器知道\def它的规则并且可以做到这一点!现在你这样做:

\csname def\expandafter\endcsname
\csname loop\expandafter\endcsname
\expandafter#\expandafter1\csname loop\expandafter\endcsname
\expandafter{\csname def\expandafter\endcsname\csname body\endcsname{#1}\iterate}

并使用\loop...\loop。TeX 会理解它并知道该做什么。如果这样的 TeX 解析器实际上可以理解上述内容并知道它的含义,那么你也可以运行考试trip在其中,如果它通过了,你可以称它为 TeX :)


是啊,没错,但是这和问题有什么关系呢?

我绝不会试图评判 LaTeX 文档解析器。事实上,它们是非常有用的工具!但它们不是 TeX,所以你必须记住它们有其局限性。

例如,许多解析器知道\input{...}读取文件,因此如果它们正在寻找标签,它们将读取该文件来查找标签。但是如果您这样做\let\externaldocument\input,那么解析器将不知道now 执行完全相同的操作。对于在某个地方定义为使用 执行某些操作\externaldocument的某些包也是如此。\externaldocument\input

在这些情况下,你需要做的是帮助解析器理解你想要做什么。例如,你可以这样做:

\externaldocument{File1.tex}
\iffalse
  \input{File1.tex}
\fi

这样可以满足双方的要求。TeX 会\externaldocument按预期执行 ,并会\input因为 而跳过\iffalse。另一方面,perser 会忽略 ,\externaldocument因为它不知道它的作用,但会读取 ,\input{File1.tex}因为它也不知道 是什么\iffalse意思。

这同样适用于用户定义的命令。我上面提到的问题定义了一个命令\figthree{sample.jpg}{caption}{fig:label},它添加了一个图形、它的标题和一个标签。但词法分析器不可能知道它\figthree做了什么,也不能猜出第三个参数应该是一个标签。1这里,同样的技巧可以解决这个问题:

\figthree{sample.jpg}{caption}{fig:label}
\iffalse
  \label{fig:label}
\fi

综合起来,您的编辑器的 TeX 解析器不是 TeX,因此它对每个命令的功能了解有限,因此您必须通过提供一些提示来帮助它理解您的意思,或者教它如何理解您的意思(如果它可以编程的话)。


1当然,在链接的问题中,Troy 展示了如何让 TeXStudio 理解命令的作用\figthree。但之后你教了它一些东西,它就不再猜测了。

相关内容