1

When using the subfiles package, is there some command to get the main document's name, even when compiling one of the child documents?

Here's a MWE showing what I mean:

\RequirePackage{filecontents}
%
\begin{filecontents*}{main.tex}
\documentclass{article}
\usepackage{subfiles}
\end{filecontents*}
%
\documentclass[main.tex]{subfiles}
\begin{document}
Child document's name: \jobname % this displays 'Child document's name: <the_name_you_gave_to_this_document>

Main document's name: % <some_command>  -- this should display 'Main document's name: main'
\end{document}

Where <some_command> is the command I'm looking for.

0

The option you pass to the subfiles class is stored in \preamble@file, which is later \input by the class. To get the base name of the file you can use LaTeX's \filename@parse, which will store the base name in \filename@base:

\RequirePackage{filecontents}
%
\begin{filecontents*}{main.tex}
\documentclass{article}
\usepackage{subfiles}
\makeatletter
\let\noibe@ifloaded\@ifl@aded
\def\mainfilename{%
  \noibe@ifloaded{cls}{subfiles}%
    {\filename@parse{\preamble@file}\filename@base}
    {\jobname}%
}
\makeatother
\begin{document}
Child document's name: \jobname % this displays 'Child document's name: <the_name_you_gave_to_this_document>

Main document's name: \mainfilename % -- this should display 'Main document's name: main'
\end{document}
\end{filecontents*}
%
\documentclass[main.tex]{subfiles}
\makeatletter
\let\noibe@ifloaded\@ifl@aded
\def\mainfilename{%
  \noibe@ifloaded{cls}{subfiles}%
    {\filename@parse{\preamble@file}\filename@base}
    {\jobname}%
}
\makeatother
\begin{document}
Child document's name: \jobname % this displays 'Child document's name: <the_name_you_gave_to_this_document>

Main document's name: \mainfilename % -- this should display 'Main document's name: main'
\end{document}

The command checks if the loaded class is subfiles. If it is, you're in a child file and the main file name is stored in \preamble@file. Otherwise you're in the main file and the file name is \jobname itself. When you're in the main file the command \preamble@file does not exist, so the command checks which class is loaded and acts accordingly.

  • One minor hiccup: this returns main.tex, how can I remove the .tex and simply get main? – noibe Apr 29 at 23:14
  • @noibe I updated the answer. – Phelype Oleinik Apr 29 at 23:16
  • Another (this time not so) minor hiccup: that code only works when compiling the "child" file. If I try to use it in the main file, I get the error Undefined control sequence. <argument> \preamble@file. – noibe Apr 29 at 23:20
  • @noibe Updated again :-) – Phelype Oleinik Apr 29 at 23:28
  • Hey thanks a lot man :) – noibe Apr 29 at 23:32

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.