5

I cannot figure out how in the world I am suppose to reference other sections in subfiles. I have prepared a simple example below:

main

\documentclass[12pt,letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage{xr}
\usepackage{subfiles}

\begin{document}
\subfile{Afile}
\subfile{Bfile}
\end{document}

Afile

\documentclass[main.tex]{subfiles}
\begin{document}
\section{Blah Blah}
\label{section: asection}
blah blah blah blah 
\end{document}

Bfile

\documentclass[main.tex]{subfiles}
\begin{document}
\section{Bo bo boooooo}
\label{section: bsection}
Unlike section \ref{section: asection}.
\end{document}

If I compile the main file everything works correctly. I can't figure out how to compile the subfiles separately and get the cross referencing to other subfiles to work. I can get the compiling of the subdocument to work by using to \externaldocument{Afile} in the preamble of the bfile but it breaks the compilation of the main file. Is there any way I can get both main and subfile to crossref correctly? If you need more clarification feel free to ask.

AzJ
  • 261

1 Answers1

2

The commands which underlie the document-environment are \document and \enddocument.

When a sub-file is loaded by the main TeX file, the command \document is redefined to deliver no tokens: It equals the command \empty from the LaTeX 2ε-kernel but unlike the \empty-command it is redefined in terms of \long.

As long as package-authors/maintainers of the subfiles-package do not decide to change this behavior, you can have LaTeX check within the preambles of your sub-files whether the definition of the command \document equals that \long-\empty-command. If so, the sub-file is loaded from the main TeX file via the \subfile-command and \externaldocument is not needed. If not so, the sub-file is compiled "standalone" and \externaldocument is needed.

Could look like this:

main.tex

\documentclass[12pt,letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage{xr}
%\usepackage{xr-hyper} % in case of also loading hyperref.
\makeatletter
\newcommand\longempty{}%
\newcommand\DoIfAndOnlyIfStandAlone{%
  \ifx\document\longempty
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
}%
\makeatother
\usepackage{subfiles}
\begin{document}
\subfile{Afile}
\subfile{Bfile}
\end{document}

Afile.tex

\documentclass[main.tex]{subfiles}
\DoIfAndOnlyIfStandAlone{%
  \externaldocument{Bfile}%
}%
\begin{document}
\section{Blah Blah}
\label{section: asection}
blah blah blah blah 
\end{document}

Bfile.tex

\documentclass[main.tex]{subfiles}
\DoIfAndOnlyIfStandAlone{%
  \externaldocument{Afile}%
}%
\begin{document}
\section{Bo bo boooooo}
\label{section: bsection}
Unlike section \ref{section: asection}.
\end{document}

A source of irritation in conjunction with the xr-package/\externaldocument not mentioned in the manual of the subfiles-package/documentclass might be LaTeX's \include..\includeonly-mechanism:

The manual of the subfiles-package says that when using the subfiles-package one shall use the command \subfileinclude instead of the command \include.

LaTeX does nonetheless for each file that is imported via \include/\subfileinclude instead of \input/\subfile create a separate/partial .aux-file whose filename equals the name of the included .tex-file and whose filename-extension is .aux .

Therefore the filename of the .aux-file created during standalone-compilation of a sub-file will be the same as the filename of the partial .aux-file created during compilation of the main TeX file when loading the sub-file in question via \subfileinclude.

Thus, when using \include/\subfileinclude make sure to have the corresponding partial .aux-file that comes from compiling main.tex removed when switching from compiling main.tex to compiling the sub-file in question standalone. Vice versa make sure to have the .aux-file that comes from compiling the sub-file in question standalone removed when switching from compiling the sub-file in question standalone to compiling main.tex.

In case of cross-referencing between different documents, you might be interested in an outline of how cross-referencing is implemented in LaTeX. I tried to explain these things in my answer to the question "How to prevent reference to enumeration inside new environment?".

Besides this, when cross-referencing between different documents by means of the xr-package/by means of the xr-hyper-package, uniqueness of names of destinations for hyperlinks might be a problem when loading hyperref for also having hyperlinks along with the cross-references. In my answer to the question "Cross-reference with `xr` package and final PDF combination?" I elaborated on how you can work around such problems when using the dvipdfmx-driver and converting from .dvi to .pdf by means of the dvipdfmx-program (, which is, e.g., the automatized default with TeX-engines based on XeTeX).

Ulrich Diez
  • 28,770
  • 1
    Thank you for your detailed explanation. What are the commands \@gobble and \@firstofone? – AzJ Dec 02 '19 at 20:40
  • 1
    @AzJ These commands are defined in the LaTeX 2e-kernel. \@firstofone just takes an argument and delivers it. \@gobble just takes an argument and doesn't deliver it/does gobble it. ;-) The command \makeatletter turns the character @ into an ordinary character that is treated like a and b and c etc, so you can use it within macro-names. The command \makeatother turns @ into a non-letter like ! or ? so that it cannot be used within macro-names any more. – Ulrich Diez Dec 02 '19 at 20:46
  • Thanks for the clarification. – AzJ Dec 02 '19 at 20:49
  • 1
    @AzJ When LaTeX gathers an argument for a macro and delivers that argument during macro-expansion, the outermost level of curly braces surrounding the entire argument at the time of gathering (if present ) will be stripped off at the time of delivering. You can use \show<control sequence> in order to have (La)TeX display on the terminal what <control sequence> does. After \makeatletter you can use \show\@gobble or \show\@firstofone in order to have (La)TeX display on the terminal what the command \@gobble respective \@firstofone does/is. – Ulrich Diez Dec 02 '19 at 20:50
  • 1
    @AzJ Btw: \expandafter in front of \@gobble/\@firstofone serves the purpose of havng LaTeX expand the token \else (and thus remove the entire \else..\fi-branch respective having LaTeX expand the \fi (and thus remove it) bevore expanding \@gobble/\@firstofone. Without these \expandafter, in the if-branch LaTeX would grab the token \else as argument for \@gobble and in the else-branch LaTeX would grab the token \fi as argument for \@firstofone. With \expandafter these things are removed and \@gobble/\@firstofone can grab the {\externaldocument...}-thingie. – Ulrich Diez Dec 02 '19 at 21:04
  • @AzJ I must correct myself. I said: "The command \makeatother turns @ into a non-letter like ! or ? so that it cannot be used within macro-names any more". This should be: "The command \makeatother turns @ into a non-letter like ! or ? so that it cannot be used within multiletter-control-sequence-names any more". – Ulrich Diez Dec 02 '19 at 21:12