Aller au contenu

This article explains, and demonstrates, the xr package which enables access to, and use of, cross-referencing labels present in external, standalone, LaTeX files. Here, we define a standalone LaTeX file as one which can be compiled because it contains a \documentclass{...} statement and the \begin{document}...\end{document} construct.

LaTeX files specifically written/structured to be included within a “container” document are not standalone because they cannot be compiled without being incorporated into another, suitable, file.

When should I use the xr package?

The following notes explain the types of projects that do, and do not, need to use the xr package.

Projects where the xr package is not required

Large LaTeX projects, such as books or long reports, are often split into a series of smaller .tex files; for example, one .tex file per book chapter. Typically, such book chapters are not standalone: you cannot compile individual chapters because they do not contain a \documentclass{...} statement or the \begin{document}...\end{document} construct. Those chapters are destined for inclusion into a “container” document which can be compiled. In those circumstances, cross-referencing to document elements—within any individual chapter file—can proceed as normal: you do not need to use the xr package.

To explore an example of a large project you can  open this example in Overleaf.

Cross-referencing 101

To cross-reference an item in a LaTeX document you need to:

1. give it a unique identifier, some_string, using the \label command:
2. \label{some_string}

3. then, at the location where you want to reference that element, you need to write
4. \ref{some_string}


To be very brief, LaTeX manages cross-referencing by writing data to a file called filename.aux where filename is the name of the main .tex file being compiled.

For the process to work, the LaTeX document has to be compiled at least twice: the first compilation generates the reference data—writing it to filename.aux. During the second compilation, LaTeX reads filename.aux to resolve the references, providing data to replace instances of \ref{some_string}.

Projects where the xr package is required

Suppose you have a set of fully-formed, standalone, LaTeX documents such as a collection of N articles: article1.tex, article2.tex ... articleN.tex. Each article can be compiled separately and it is likely they were written using a variety of document classes, packages etc.

Now imagine there’s a need to write another article, summary.tex, say, which has to reference sections, figures, tables etc contained within those individual, standalone, articles. The xr package let’s you do that: it enables summary.tex to reference labels generated by any of the standalone article*.tex papers.

A note on .aux files

• Note, here we are using an asterisk (*) as a placeholder for any number from 1 to N.

Compiling any of the standalone files article1.tex, article2.tex ... articleN.tex causes LaTeX to generate a corresponding article*.aux (auxillary) file which, among other items, contains label data required to generate cross-references.

If any of the article*.tex files are edited, including changing, adding or removing labels (\label{..}), the corresponding article*.tex file(s) need to be recompiled, particularly if updated article*.aux file(s) are required.

Detecting changes to article*.tex, and subsequently recompiling them, can be automated on Overleaf by using a suitable latexmkrc file.

How to use xr on Overleaf

We will follow our multiple article-file example to demonstrate using the xr package on Overleaf; in particular, we show how to automate the compilation process via a latexmkrc file. Our example is based on code contained in an answer on tex.stackexchange, written by a user called cyberSingularity.

The files used in our example

To streamline the example, our project contains just the following files:

• article1.tex: a single article which, internally, uses cross-references. We want to use those same references within the summary, summary.tex, which requires accessing reference data in the article1.aux file.
• summary.tex: the document that needs to reference document elements, such as figures and sections, contained in article1.tex.
• latexmkrc: contains code (Perl) to automate recompilation of article1.tex due to any changes made to it.

Process outline

• In our example, the file article1.tex is untouched, it is used as written or provided by the original author.
• summary.tex loads the xr package and has some some additional LaTeX code which
• enables it to access reference data contained in article1.aux;
• enables latexmkrc to automatically recompile article1.tex, if required—e.g., if article1.tex is edited requiring an updated article1.aux file.
• a latexmkrc file is written.

The first step is to load the xr package in the main file you are working on. In this case, this simply means we include

\usepackage{xr}


in the preamble of summary.tex.

• Note: If you’re using the hyperref package in your main file (summary.tex), then load xr-hyper instead of xr in summary.tex before hyperref. You’ll also need to load the hyperref package in the external document (i.e., article1.tex).

The \externaldocument command

The xr package provides the \externaldocument command which has the general form

\externaldocument[prefix]{external_file}


where the optional [prefix] is used to prevent duplicate labels. By way of example, if your main .tex file, e.g. summary.tex, and the external file, article1.tex, both contain \label{eq:1} you can avoid a name clash by writing

\externaldocument[art1-]{article1}


in which case all references from article1.tex are prefixed by art1-. Now you can access \label{eq:1}, contained in article1.tex, by writing \ref{art1-eq:1} in summary.tex.

The initial files: starting points

We will use a very short article1.tex file which contains several cross-references—we want to use some of those references in summary.tex.

Note the following: compiling article1.tex will use a file called article1.aux to write and read its cross-reference data, but compiling summary.tex uses summary.aux for the same purposes. Our goal is to enable summary.tex to read cross-reference data from one or more external .aux files; here, one called article1.aux.

article1.tex

The following code can be opened in Overleaf using the link below the listing.

\documentclass{article}
\title{This is \texttt{article1.tex}}
\begin{document}
\section{Introduction}
\label{introduction}

This is a standalone \LaTeX{} document with
references we want to use in \texttt{summary.tex}.

\subsection{Math references}
\label{mathrefs}
As mentioned in section \ref{introduction},
different elements can be referenced within
a document.

\subsection{Powers series}
\label{powers}

\begin{equation}
\label{eq:1}
\sum_{i=0}^{\infty} a_i x^i
\end{equation}

Equation \ref{eq:1} is a typical power series.
\end{document}


Compiling article1.tex produces the following output:

summary.tex

Here is our initial, minimal, summary.tex file prior to adding the code required to access external cross-references created in article1.tex.

Note that summary.tex does not contain any \label{some_string} commands that correspond to each \ref{some_string}. If we compile this version of summary.tex it will attempt to read reference data from summary.aux but, of course the required data is contained in the external article1.aux file which cannot, yet, be accessed.

Observe that the xr package is loaded but that alone is not enough to resolve the cross-references: additional code is required to access the external article1.aux file.

\documentclass{article}
\usepackage{xr}
\title{This is \texttt{summary.tex}}
\begin{document}

In the file \texttt{article1.tex}, the introduction is section \ref{introduction}.  In that file, there are two subsections: \ref{mathrefs} and \ref{powers}. In subsection \ref{powers}, equation \ref{eq:1} demonstrates a power series.
\end{document}


Compiling this incomplete summary.tex file produces the following output, with double question marks showing undefined references:

Overleaf reports the undefined references:

Extra code for summary.tex: accessing external references

The following code creates the \myexternaldocument{...} which allows you to specify the external document whose labels you would like to reference from within summary.tex.

\makeatletter
\typeout{(#1)}% latexmk will find this if $recorder=0 % however, in that case, it will ignore #1 if it is a .aux or % .pdf file etc and it exists! If it doesn't exist, it will appear % in the list of dependents regardless) % % Write the following if you want it to appear in \listfiles % --- although not really necessary and latexmk doesn't use this % \@addtofilelist{#1} % % latexmk will find this message if #1 doesn't exist (yet) \IfFileExists{#1}{}{\typeout{No file #1.}} }\makeatother \newcommand*{\myexternaldocument}[1]{% \externaldocument{#1}% \addFileDependency{#1.tex}% \addFileDependency{#1.aux}% }  Specifying the external document Once the helper code (above) is added to summary.tex, the next step is to specify the external document whose labels you would like to reference. This is the only part of the code you will have to change yourself depending on the name of the file. \myexternaldocument{article1}  Here, article1 can be replaced by any file whose labels you want to access—you can use multiple \myexternaldocument commands to access additional external files. Creating the latexmkrc file The next step is to create a latexmkrc file as shown below: • In your project editor window, select the New File icon at the top-left of the project window. • Select New File from within the Add Files pop-up dialog box and name the file latexmkrc—note there is no file extension: • Make sure that the latexmkrc file created and saved in the top (root) level of the project’s files area. That is, not inside any folders in the file tree. • Add the following code to the file latexmkrc: add_cus_dep( 'tex', 'aux', 0, 'makeexternaldocument' ); sub makeexternaldocument { if (!($root_filename eq $_[0])) { system( "latexmk -cd -pdf \"$_[0]\"" );
}
}


This compiles the external document article1.tex using the pdfLaTeX engine, and the auxiliary files produced are saved in the cache to be accessed and referenced whilst summary.tex is compiled. If your external file needs to be compiled with a different engine, the appropriate command should be commented out from the following (by removing the preceding #; here, pdfLaTeX is used again):

add_cus_dep( 'tex', 'aux', 0, 'makeexternaldocument' );

sub makeexternaldocument {
if (!($root_filename eq$_[0]))
{
# FOR PDFLATEX
system( "latexmk -cd -pdf \"$_[0]\"" ); # FOR LATEX+DVIPDF # system( "latexmk -cd \"$_[0]\"" );

# FOR XELATEX
# system( "latexmk -cd -xelatex \"$_[0]\"" ); # FOR LUALATEX # system( "latexmk -cd -lualatex \"$_[0]\"" );
}
}


The final Overleaf project files

The following three-file project can now be opened in Overleaf using the links provided above and below the file listings.

summary.tex

This is our summary file. From within this file we want to use cross-references created in external files. Here, we want to use labels generated in article1.tex.

% This code is derived from an answer on tex.stackexchange
% (by cyberSingularity at http://tex.stackexchange.com/a/69832/226)

\documentclass[12pt]{article}

\title{Using the xr package on Overleaf}

%----Helper code for dealing with external references----
% (by cyberSingularity at http://tex.stackexchange.com/a/69832/226)

\usepackage{xr}
\makeatletter

\typeout{(#1)}% latexmk will find this if $recorder=0 % however, in that case, it will ignore #1 if it is a .aux or % .pdf file etc and it exists! If it doesn't exist, it will appear % in the list of dependents regardless) % % Write the following if you want it to appear in \listfiles % --- although not really necessary and latexmk doesn't use this % \@addtofilelist{#1} % % latexmk will find this message if #1 doesn't exist (yet) \IfFileExists{#1}{}{\typeout{No file #1.}} }\makeatother \newcommand*{\myexternaldocument}[1]{% \externaldocument{#1}% \addFileDependency{#1.tex}% \addFileDependency{#1.aux}% } %------------End of helper code-------------- % put all the external documents here! \myexternaldocument{article1} \begin{document} In the file \texttt{article1.tex}, the introduction is section \ref{introduction}. In that file, there are two subsections: \ref{mathrefs} and \ref{powers}. In subsection \ref{powers}, equation \ref{eq:1} demonstrates a power series. \end{document}  article1.tex This file is one of our articles. Note how it contains various \label commands to create labels that, thanks to the xr package, we can use in the file summary.tex. \documentclass{article} \title{This is \texttt{article1.tex}} \begin{document} \section{Introduction} \label{introduction} This is a standalone \LaTeX{} document with references we want to use in \texttt{summary.tex}. \subsection{Math references} \label{mathrefs} As mentioned in section \ref{introduction}, different elements can be referenced within a document. \subsection{Powers series} \label{powers} \begin{equation} \label{eq:1} \sum_{i=0}^{\infty} a_i x^i \end{equation} Equation \ref{eq:1} is a typical power series. \end{document}  latexmkrc This latexmkrc file contains code to ensure the external files are compiled. add_cus_dep( 'tex', 'aux', 0, 'makeexternaldocument' ); sub makeexternaldocument { if (!($root_filename eq $_[0])) { # FOR PDFLATEX system( "latexmk -cd -pdf \"$_[0]\"" );

# FOR LATEX+DVIPDF
# system( "latexmk -cd \"$_[0]\"" ); # FOR XELATEX # system( "latexmk -cd -xelatex \"$_[0]\"" );

# FOR LUALATEX
# system( "latexmk -cd -lualatex \"\$_[0]\"" );
}
}


The following graphic is an annotated version of the output from typesetting summary.tex, showing the cross-references and the corresponding labels from the external file article1.tex.

The external documents are compiled automatically via the latexmkrc file; consequently, any LaTeX syntax errors within them won’t show in the Overleaf interface—unless you recompile them in Overleaf too. Errors in those external files could prevent cross-references from appearing correctly in the typeset PDF file, so we strongly recommend checking and correcting any such errors as soon as they occur.