0

I have three tex files: File 1. Main paper; File 2. Supplementary file; File 3. A referee report. As you can see there is no "master" file. However, I want to be able refer labels in one file in another file. I use the xr package to do this. However, Latextools (in Sublime Text 3) doesn't seem to recognize this and doesn't provide the labels in the other files as options in the auto completion lists.

File 1 is as following:

\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}

File 2 is as following:

\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}

I tried to look at the "latex_ref_completions.py" but where it says that Latextools "recursively search all linked tex files to find all" but I am not sure how to "link" these two files.

  • Welcome to TeX.SX! You have to remember that "only TeX can parse TeX". This means that Sublime's parser doesn't know that it is supposed to look for labels in the file given to \externaldocument. It probably only knows \input and \include. You can try to trick it adding \iffalse\input{File2.tex}\fi. No guarantee that it will work, but... – Phelype Oleinik Aug 14 '18 at 0:21
1

I'll leave an answer because there was a similar question just 3 days ago.

The problem here is the classic "only TeX can parse TeX". But what does that even mean? Most actual programming languages have a somewhat fixed syntax. For example, in C (not that I know C, but...) a for statement will always have the same syntax and do the same thing, no matter what, because that's how C works. The code:

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

will always, anywhere, print 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,. A program in plain-TeX that would do the same is:

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

because \loop is defined as:

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

The thing is, in C, any lexer will know how to do the proper syntax highlighting (if the code is not obfuscated, of course) and it will, in principle, be correct. In TeX, if some syntax highlighting program tries to be clever and know what the \loop...\repeat does, you can easily fool it:

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

then just use \loop...\nope, and the lexer will get lost. This (sort of) explains why "only TeX can parse TeX". TeX will know that the meaning of \loop has change and will use it accordingly, but the lexer would have to parse that \def and update its definition of \loop to make the proper choices.

But let's be optimistic and suppose our non-TeX TeX parser knows \def and its rules and can do that! Now you do this:

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

and use \loop...\loop. TeX will understand it and know what to do. If such a TeX parser can, in fact, understand the above and know what it means, then you may as well run the trip test in it and if it passes you can call it TeX :)


Yeah, right, but what does this have to do with the question?

I am, by no means, trying to judge LaTeX document parsers. They are in fact very helpful tools! But they are not TeX, so you have to remember they have their limitations.

For example, many parsers know that \input{...} reads in a file, so if they are looking for labels they will read that file looking for them. But if you do \let\externaldocument\input, then the parser won't know that \externaldocument now does exactly the same thing. The same goes for some package that, somewhere, defines \externaldocument to do something with \input.

What you have to do in these situations is to help the parser to understand what you want to do. You can, for example, do:

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

This will satisfy both ends. TeX will execute the \externaldocument as it is supposed to, and will skip the \input because of the \iffalse. The perser, on the other hand, will ignore the \externaldocument because it doesn't know what it does, but will read the \input{File1.tex} because it also doesn't know what \iffalse means.

The same applies for user-defined commands. The question I mentioned above defines a command \figthree{sample.jpg}{caption}{fig:label}, which adds a figure, its caption, and a label. But the lexer can't possibly know what \figthree does, neither can it guess that the third argument is supposed to be a label.1 There, the same trick would work around the problem:

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

In synthesis, your editor's TeX parser is not TeX, so it has limited knowledge of what each command does, so you have to help it understand what you mean by giving it some hints, or teaching it how to understand what you meant, if it can be programmable.


1 Of course, in the linked question, Troy showed how you can make TeXStudio's understand what the \figthree command does. But then you taught it something and it's no longer guessing.

  • Thanks for the detailed explanation. It was and will be helpful to me the future. – Statguy Aug 14 '18 at 15:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.