2

Is there a way to renew a command only when the child file is compiled with the subfiles-package?

main.tex:

\documentclass{article}
\usepackage{subfiles}
\newcommand{\foo}{foo}

\begin{document}
  \foo % always returns foo
  \subfile{content}
\end{document}

content.tex:

\documentclass[main.tex]{subfiles}
\renewcommand{\foo}{bar}

\begin{document}
  Here is some content.
  \foo % always returns bar
\end{document}

When I compile main.tex the \foo called from inside content.tex returns bar. I want it to return foo when I compile main.tex and bar when I compile content.tex. Is this possible?

The documentation for subfiles, section 2.2, state that:

• If the subordinated file was \subfile’d, it ignores everything before and including \begin{document}, and the ignores \end{document} too. (The body of the file, nothing else, is effectively \input.)

This does not seem to be the case.

neic
  • 379
  • 2
  • 13
  • It could be possible by using a \if... statement...I'll take a look –  Aug 12 '14 at 20:47

3 Answers3

3

This uses a internal feature of the subfiles class (see doc please)

The class defines \old@document@subfiles. If this is present, it is the class running, otherwise the package only. It is quite easy to check for the definition using etoolbox \ifdef{} and then define the commands accordingly.

enter image description here

(The screen shot is taken from the documentation subfiles.pdf)

\documentclass{article}
\usepackage{etoolbox}%
\usepackage{subfiles}%


\makeatletter
\ifdef{\old@document@subfiles}{%
  \newcommand{\foo}{bar}%
}{%
 \newcommand{\foo}{foo}%
}%
\makeatother


\begin{document}
  \foo % always returns foo
  \subfile{content}
\end{document}
  • Thank you. This works as intended. A warning to others: This is a hack and could easily break if subfiles is updated. – neic Aug 16 '14 at 15:25
  • @neic: Of course it is a hack, as the request involved a feature not designed in the package ;-) –  Aug 16 '14 at 22:30
  • @ChristianHupfer I use subfiles and todonotes and wanted to have a TOC and a listoftodos also seperately for each subfile when compiled for itself, but only one when compiled from the master file. With your trick I simply defined a \subfileonly command in the preamble of the main document (which expands to \listoftodos \tableofcontents instead of "bar" and is empty instead of "foo" in my case) and placed \subfileonly after \begin{document} in each of the subfiles. Very nice indeed! – Cornelius Sicker Aug 17 '16 at 08:34
1

A sketch, with the assumption, that you know, if subfiles is used and you mark this by \subfilestrue.

\documentclass{article}

\begin{document}
\newif\ifsubfiles

\newcommand{\foo}{FOO}

\foo
\renewcommand{\foo}{\ifsubfiles BAR\else FOO\fi}

A \foo

\subfilestrue

B \foo

\end{document}
0

You could check if you are in the preamble or in the actual text using \ifx\@onlypreamble\@notprerr#1\else#2\fi as suggested in this answer. Adjusted to your case:

main.tex

\documentclass{article}
\usepackage{subfiles}
\makeatletter
\newcommand{\insubfile}[1]{\ifx\@onlypreamble\@notprerr\else#1\fi}
\makeatother
\newcommand{\foo}{foo}

\begin{document}
\foo % always returns foo
\subfile{content}
\end{document}

content.tex

\documentclass[main.tex]{subfiles}
\insubfile{\renewcommand{\foo}{bar}}

\begin{document}
  Here is some content.
  \foo % always returns bar
\end{document}

This gives the desired result and does not depend on internal macros of the subfiles package.

Jan Hajer
  • 864