A common scenario we come across is that we have a main manuscript document and a supplementary information document, each of which have their own sections, tables and figures. The question then becomes – how do we effectively cross-reference between the documents without having to tediously count all the numbers ourselves every time we make a change and recompile the documents?
The answer: cross referencing!
This solution is based on the tex stackexchange thread found here: https://tex.stackexchange.com/questions/62142/latexmk-with-external-references
Create two *.tex files that will contain the source code for you documents. For example: main.tex for your manuscript and SI.tex for your supplementary information.
Add the following code to the header of both files.
\usepackage{xr}
\makeatletter
\newcommand*{\addFileDependency}[1]{
\typeout{(#1)}
\@addtofilelist{#1}
\IfFileExists{#1}{}{\typeout{No file #1.}}
}\makeatother
\newcommand*{\myexternaldocument}[1]{%
\externaldocument{#1}%
\addFileDependency{#1.tex}%
\addFileDependency{#1.aux}%
}
Then, create a new file called “latexmkrc” and paste the following code into it:
$sub_doc_output = 'output-subdoc';
@sub_doc_options = ();
push @sub_doc_options, '-pdf'; # Use pdflatex for compilation of external documents.
# Replace '-pdf' by '-pdfdvi', 'pdfxe', or 'pdflua' if needed.
push @file_not_found, '^No file\\s*(.+)\s*$';
add_cus_dep( 'tex', 'aux', 0, 'makeexternaldocument' );
sub makeexternaldocument {
if ( $root_filename ne $_[0] ) {
my ($base_name, $path) = fileparse( $_[0] );
pushd $path;
my $return = system "latexmk",
@sub_doc_options,
"-aux-directory=$sub_doc_output",
"-output-directory=$sub_doc_output",
$base_name;
if ( ($sub_doc_output ne ' ') && ($sub_doc_output ne '.') ) {
rdb_add_generated( "$sub_doc_output/$base_name.aux" );
copy "$sub_doc_output/$base_name.aux", ".";
}
popd;
return $return;
}
}
Finally, add a command declaring the external document before the \begin{document} statement in each of the files. So in main.tex add:
\myexternaldocument{SI}
And to SI.tex add:
\myexternaldocument{main}
After recompiling you can now reference labels across documents using the usual:
\ref{my_item_label}
Here is a minimal working example with main.tex:
\documentclass{article}
\usepackage{graphicx}
\usepackage{xr}
\makeatletter
\newcommand*{\addFileDependency}[1]{
\typeout{(#1)}
\IfFileExists{#1}{}{\typeout{No file #1.}}
}\makeatother
\newcommand*{\myexternaldocument}[1]{%
\externaldocument{#1}%
\addFileDependency{#1.tex}%
\addFileDependency{#1.aux}%
}
\myexternaldocument{SI}
\title{mini cross reffing example}
\author{npq15 }
\date{November 2024}
\begin{document}
\maketitle
\section{Introduction}
\begin{figure}
\centering
\caption{Caption}
\label{fig:main}
\end{figure}
I am referencing a SI figure: \ref{fig:SI}
\end{document}
… and SI.tex:
\documentclass{article}
\usepackage{graphicx} % Required for inserting images
\usepackage{lipsum}
\usepackage{xr}
\makeatletter
\newcommand*{\addFileDependency}[1]{
\typeout{(#1)}
\@addtofilelist{#1}
\IfFileExists{#1}{}{\typeout{No file #1.}}
}\makeatother
\newcommand*{\myexternaldocument}[1]{%
\externaldocument{#1}%
\addFileDependency{#1.tex}%
\addFileDependency{#1.aux}%
}
\myexternaldocument{main}
\title{mini cross reffing example SI}
\author{npq15 }
\date{November 2024}
\begin{document}
\maketitle
\section{SI}
\begin{figure}
\centering
\caption{SI figure}
\label{fig:SI}
\end{figure}
I am referencing a main figure: \ref{fig:main}
\end{document}
Happy LaTEXing 🙂
